Magento Block Extension - Ajax Controller Html Output Layout - html

Currently, i'm working on an AJAX-Controller for my finished Extension.
AjaxController.php - Controller
Lager.php - Extension itself - has HTML outputs
the extension Lager.php runs only on the product view page, styled via catalog.xml in base/default/layouts and shows up under the pricebox.
So. The AjaxRequest, which is sent up by another extension which doesn't matters, works fine like the AjaxController too. But there's a problem. In AjaxController.php i've got a command to execute a function in Lager.php. It does, and with firebug i'm able to see, that he got the right response (the HTML output) too, but i think the layout is false. .. The new Html doesn't show up anywhere on the product view.
AjaxController.php (works fine but no HTML output, or no styling.. cause in html output in firebug theres no included css anymore):
<?php
require_once "Mage/Catalog/controllers/ProductController.php";
class Lager_Lager_AjaxController extends Mage_Catalog_ProductController
{
public function indexAction()
{
$this->loadLayout();
$this->renderLayout();
}
public function refreshAction()
{
$selected = $this->getRequest()->getParam('selected');
if($selected == 'true')
{
$productId = $this->getRequest()->getParam('productid');
if($productId)
{
$block = $this->getLayout()->getBlockSingleton('lager/lager')->runLager($productId); //does html output
}
}
else
{
}
}
}
?>
The config.xml part of the ajax implementation:
<frontend>
<routers>
<lager>
<use>standard</use>
<args>
<module>Lager_Lager</module>
<frontName>lager</frontName>
</args>
</lager>
</routers>
</frontend>
the catalog.xml part of the extension implementation:
<block type="catalog/product_view" name="product.info" template="catalog/product/view.phtml">
<!--
<action method="addReviewSummaryTemplate"><type>default</type><template>review/helper/summary.phtml</template></action>
<action method="addReviewSummaryTemplate"><type>short</type><template>review/helper/summary_short.phtml</template></action>
<action method="addReviewSummaryTemplate"><type>...</type><template>...</template></action>
BEGIN LAGER IMPLEMENTATION -->
<block type="lager/lager" name="lager" template="lager/lager.phtml" /> <!-- Lager Einbindung -->
<lager_ajax_refresh>
<block type="lager/lager" name="lager" output="toHtml" template="lager/lager.phtml" />
</lager_ajax_refresh>
<!-- END -->
<block type="catalog/product_view_media" name="product.info.media" as="media" template="catalog/product/view/media.phtml"/>
<block type="core/text_list" name="alert.urls" as="alert_urls" translate="label">
<label>Alert Urls</label>
</block>
<action method="setTierPriceTemplate"><template>catalog/product/view/tierprices.phtml</template></action>
So the Ajax Controller doesn't use the layout configuration of the extension which is implemented in catalog.xml ..
http://www.directupload.net/file/d/3601/h94loqef_png.htm

Related

Struts 2 there's no action mapped

I have a Struts 2 application where I'm creating a function Export to Excel. I am using a button that is not inside a s:form tag
<button class="action-button" id = "exportToExcel" style="float: right;height: 2em;padding: 0 1em; margin-right: 2%;" onClick="exportTableToExcel()">Export to Excel</button>
In the exportTableToExcel() i'm making an ajax call to send html table(pivot report data) to be sent as json data.
In my ajax call the url is specified as :
url: './pivotSaveToExcelAction/createExcelReport.action'
The struts.xml entry is as follows:
<package name="pivotSaveToExcelAction" namespace="/pivotSaveToExcelAction" extends="json-default">
<action name="createExcelReport" class="....PivotSaveToExcelAction">
<result type="json"/>
</action>
</package>
Can anyone tell me where i'm going wrong?
I get the error:
There's no action mapped for namespace /reports/pivotTable/pivotSaveToExcelAction and action name createExcelReport.

CoordinatorLayout does not hide Toolbar on scrolling despite implementing all required parameters

Here is my setup, i am running a DrawerLayout, within it is a CoordinatorLayout containing an AppBarLayout and a nestedscrollview. I am trying to have the nestedscrollview scroll normally and the Toolbar to get hidden on scrolling down and reppear on scrolling up. Attached within is my XML code. Would appreciate any help.. have read all related questions and implemented their answers without any success.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout_admin"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/admincoordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/adminrelScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/menu_drawer" />
I have had the same issue for a week and tried almost everything to solve it.
However I managed to solve the issue.
Where you have something like...
<include
android:id="#+id/app_bar"
layout="#layout/app_bar"
app:layout_scrollFlags="scroll|enterAlways" />
...replace this with whatever is in your app_bar.xml layout. For example:
<android.support.v7.widget.Toolbar
android:id="#+id/main_toolbar"
style="#style/AppTheme.Toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_scrollFlags="scroll|enterAlways"/>
It seems that for some reason, scrolling with CoordinatorLayout does not work when using the <include> tag.
I think making use of the new CollapsingToolbarLayout will help…
A short description from some very useful exploration of the new Android Design Support Library shows how to wrap a Toolbar in a CollapsingToolbarLayout and customize effects by setting layout_collapseMode.
update
I think adding an onScrollListener to your ListView and showing/hiding the toolbar like this example from this answer:
getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
listView.setOnScrollListener(new OnScrollListener() {
int mLastFirstVisibleItem = 0;
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) { }
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (view.getId() == listView.getId()) {
final int currentFirstVisibleItem = listView.getFirstVisiblePosition();
if (currentFirstVisibleItem > mLastFirstVisibleItem) {
getSupportActionBar().hide();
} else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
getSupportActionBar().show();
}
mLastFirstVisibleItem = currentFirstVisibleItem;
}
}
});
As #Farbod Salamat-Zadehwas said before: CoordinatorLayout does not work when using the <include> tag.
But you can use <include> this way:
<include
android:id="#+id/app_bar"
layout="#layout/app_bar" />
Parameter app:layout_scrollFlags="scroll|enterAlways" just should be moved into your app_bar.xml if it acceptable for you

Autocomplete in MVVMCross Xamarin (Android)

I am trying to create an autocomplete control in Xamarin Android based layout. I am using MVVMCross.
I have created the following AXML layout in my fragment.
<TextView
android:text="Item"
android:layout_column="0"
android:id="#+id/textView42"
android:layout_height="28.6dp"
android:layout_width="86.9dp"
android:gravity="center"
android:layout_marginTop="17.5dp"
android:layout_marginRight="17.5dp" />
<AutoCompleteTextView
android:id="#+id/autocomplete_country"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
local:MvxBind="Adapter Items" />
I had updated my viewmodel to return a string array.
private string[] _items = new string[] { "DD", "DD2" };
public String[] Items
{
get { return this._items; }
set { this._items = value; RaisePropertyChanged<string[]>(() => this._items); }
}
I think I need to use an ArrayAdapter, However I am not sure how to do it. Please provide some guidance/pointers which can help me to proceed.
I am new to Xamarin and MVVMCross, so I might be missing things here.
You don't need a custom Adapter. Switch to MvxAutoCompleteTextView and use MVVMCross binding. Here is an example of how I've used it.
<MvxAutoCompleteTextView
android:id="#+id/DrugName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:hint="Enter drug name..."
android:textSize="#dimen/text_size_xlarge"
local:MvxItemTemplate="#layout/item_drug_notclickable"
local:MvxBind="ItemsSource DrugSuggestions; PartialText DrugSearchTerm; SelectedObject Drug;"
android:layout_gravity="right" />
As Nikola said in the comments you want to be calling RaisePropertyChanged against the Items property not the private variable. That goes for all property changed calls.
One thing to watch out for with the AutoComplete is that changes to the Text must result in a change to the ItemSource. Have a look at this GitHub answer for a full explanation, https://github.com/MvvmCross/MvvmCross/issues/945 of the gotcha

Struts2 jquery autocompleter with JSON

I'm using atocompleter in my form with json.
This is the part of my struts.xml
<package name="default" extends="struts-default,json-default">
<action name="jsonSample" class="com.jaisar.jsep.product.web.action.DatabaseJSON" method="getDatabaseJSONData" >
<result type="json"/>
</action>
</package>
My jsp page is :
<%# taglib prefix="s" uri="/struts-tags" %>
<%# taglib prefix="sj" uri="/struts2-jquery-tags"%>
<s:url id="remoteurl" action="jsonSample.action"/>
<sj:select
href="%{remoteurl}"
id="echo"
name="echo"
list="languageList"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"/>
Action class method is :
public class DatabaseJSON extends ActionSupport {
private List<String> languageList;
public String getDatabaseJSONData() {
languageList = new ArrayList<String>();
languageList.add("Java");
languageList.add("PHP");
languageList.add("C#");
return SUCCESS;
}
// Setters and getters for languageList ..
}
But the page doesn't load with the autocompleter. Page shows simply a select box... Any solutions? Plz ... I refered a lot , but i couln't find the silution...
I referred the site http://code.google.com/p/struts2-jquery/wiki/SelectTag#Receive_Entrys_from_a_simple_String_List
Thanks in advance...
I would try putting dataType='json' attribute in the sj:select tag.
You didn't specify the result name in your struts.xml. Try: <result name="success" type="json">

Registering components with castle that are dynamically created by DynamicProxy

So I've been working hard for a while to build a solution which creates certain components using nothing but Castle DynamicProxy (version 2.2) and an interceptor. Everything looks great except that at the end of all this I realized I need to register these components with the windsor container. Is this possible or has my work been for naught?
I'll fabricate 2 castle configurations to explain my problem. The first one works, while the second does not.
First config (this has been working great for a while):
<castle>
<facilities>
<facility
id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>
<components>
<component
id="Factory"
service="Foo.IFactory, Foo"
type="Foo.Local.LocalFactory, Foo.Local" />
<component
id="Loader"
service="Foo.Contracts.ILoader, Foo.Contracts"
type="Foo.Local.Loader, Foo.Local"
factoryId="Factory" factoryCreate="GetLoader" />
</components>
</castle>
Second config (I don't know what to put in the type attribute and it doesn't work without it):
<castle>
<facilities>
<facility
id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>
<components>
<component
id="Factory"
service="Foo.IFactory, Foo"
type="Foo.Remote.RemoteFactory, Foo.Remote" />
<component
id="Loader"
service="Foo.Contracts.ILoader, Foo.Contracts"
type="I DUNNO, WHAT'S THE TYPE?"
factoryId="Factory" factoryCreate="GetLoader" />
</components>
</castle>
So my fabricated configs register the factory facility, then I register a factory, then register my "ILoader" component. The "LocalFactory" creates an actual type for the ILoader component, whereas the "RemoteFactory" creates the ILoader component using dynamic proxy, creating the proxies without targets. I.e., I use the ProxyGenerator.CreateInterfaceProxyWithoutTarget method, so there is no underlying class.
So, is there any hope in registering components as per the second config?
EDIT:
Unfortunately, using the fluent configuration API is not an option at the moment. So to narrow my question down, is it possible to achieve this using the XML configuration?
I believe this is possible via the Fluent Registration API and the "UsingFactoryMethod" mechanism. I have tried to replicate your fabricated scenario in the below test case.
UPDATE
This is in fact possible with XML configuration as well. The trick is just to list the interface itself as the "type" in the configuration (or, equivalently, only specify the "type", as the "service" will be set to the "type" if it is not explicitly provided). I have updated the test case below to include a "TestXml" test that uses xml configuration to achieve your desired result. The "TestFluent" test uses the fluent registration API to achieve it. FYI, I am using Castle Windsor 2.0 here, as I'm guessing that's what you're using.
using Castle.DynamicProxy;
using Castle.Facilities.FactorySupport;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;
namespace CastleTests
{
public interface ILoader
{
void Load();
}
public interface ILoaderFactory
{
ILoader GetLoader();
}
public class LoaderFactory : ILoaderFactory
{
public ILoader GetLoader()
{
return GetLoaderStatic();
}
public static ILoader GetLoaderStatic()
{
return (ILoader) new ProxyGenerator().CreateInterfaceProxyWithoutTarget(typeof (ILoader));
}
}
[TestFixture]
public class DynamicFactoryTests
{
[Test]
public void TestFluent()
{
using (var container = new WindsorContainer())
{
container.AddFacility<FactorySupportFacility>();
container.Register(
Component.For<ILoader>().UsingFactoryMethod(() => LoaderFactory.GetLoaderStatic())
);
var loader = container.Resolve<ILoader>();
Assert.That(loader.GetType().FullName, Is.EqualTo("Castle.Proxies.ILoaderProxy"));
}
}
[Test]
public void TestXml()
{
using (var container = new WindsorContainer("factory.xml"))
{
var loader = container.Resolve<ILoader>();
Assert.That(loader.GetType().FullName, Is.EqualTo("Castle.Proxies.ILoaderProxy"));
}
}
}
}
The content of "factory.xml" is thusly:
<castle>
<facilities>
<facility
id="factory.support"
type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>
<components>
<component
id="foo"
service="CastleTests.ILoaderFactory, CastleTests"
type="CastleTests.LoaderFactory, CastleTests" />
<component
id="bar"
type="CastleTests.ILoader, CastleTests"
factoryId="foo" factoryCreate="GetLoader" />
</components>
</castle>