ExtJs select component by id starting with a string - extjs

i need to create a component dynamically by a button click. My restrictions are:
It's going to has an Id starts with a fixed string like 'myComp_' and followed by a random number
At any time there will be only one component that has an id starts with 'myComp_xxx'
So before creating the component i have to check if there's any created before and remove it... My problem starts here. Ext.getCmp() wants the specific id. But i only have that fixed string : myComp_...
Is there any way to get the component created before???
Thanks in advance and sorry about my English.

For ExtJs 4.X use Ext.ComponentQuery.query('*[id^=myComp_xxx]');
For ExtJs 3.X you can either use the following
var el = Ext.query('*[id^=myComp_xxx]');
var cmp = Ext.getCmp(el.id);
Or (this one i haven't tried personally, but i think it should work) if the component is a child of a component that you can access, then:
var el = parentComp.find("action","btn");
and set a property called action : btn in the button config.

I think what you are looking for is DomQuery.
Ex:
Ext.query("*[id^=myComp_xxx]")

You need to use this: Ext.getCmp(id)
Ext.getCmp("myComp_xxx");

Sounds like you should be using the normal component query stuff - in general it is not a good idea to use id. You can query by xtype and by itemId (which you can assign manually).
The following
Ext.ComponentQuery.query('grid form');
would find all things with xtype grid that have forms inside them somewhere.
Ext.ComponentQuery.query('grid #okButton');
whereas the # here is saying look for grids that have something with itemId 'okButton' in them.
You can nest this to whatever level you need and use other operators to be more specific and as someone else has rightly pointed out you can use up and down on components to do this relative to the current component. Its worth noting that rather than getting an array back with all the results you just get the first one when you use up and down.
See the documentation for more information this.
Also see point 6 on this list of bad practices to avoid for more of the why

Another alternative if you know 'where' your component is going to be created is to use the up()/down() methods.
E.g. if you have a button and want to get the form it's contained within inside a click handler you can do something like this:
function myClickHandler(btn) {
var form = btn.up('form');
//do something with form
}

Related

How to force two instance of the same app (DNN/2sxc) to read from the same stream?

Sorry if my question is silly but I'm new to DNN/2sxc, I've spent the whole day trying to figure this with no success..
I have two instances of the same app, one in the home page and the other on its own page, each one must have its own view template (I use Razor).
My problem is I cannot figure a way to make the two apps read the same data, so every add/edit/remove/re-sort in one of them will be reflected to the other, currently each app has its own data and therefore they are unusable in my case.
I've tried to use a 'EntityTypeFilter' inside a 'Data Query' and use it in both views (as in the News-Simple demo video), it worked and gave me all the items in the two views, but another two problems come with this solution:
1- now I'm unable to use the toolbar to (add/remove/reorder,.. etc) any of the items , as you can see in this image, which is a show-stopper for me,
note: this is the toolbar I use:
#foreach(var item in AsDynamic(Data["Default"]))
{
...
#Edit.Toolbar(target: item, actions: "new,edit,replace,remove,moveup,movedown,instance-list")
2- the 'Content Demo Item' is also visible in the list, but it is not that important since I can delete it and use one of the real data items as a demo item.
I appreciate any kind of help.
Thank you.
So the first thing you should know is the difference when using content-items as data (to query, etc.) and when using it as assigned-items (where each module-instance has a subset of items). Here's the blog that should help you understand the difference: http://2sxc.org/en/blog/post/12-differences-when-templating-data-instead-of-content
So when you want the "manually and easily control the exact items displayed, their ordering etc." you want to use the "content-assigned-to-instance" which also gives you the simple add, delete buttons, as these don't really delete anything, but just remove the assignment from the module-instance.
Now your case is a bit special, in that you want to re-use the exact same set in another module-instance. There are a few ways you can do this:
Same View
if it's exactly the same view etc. just duplicate the module using DNN-features (the add-existing-module-to-another page)
different view
if it's a different view (maybe more compact, etc.) you again have multiple options. The first is to mirror / duplicate using the dnn-feature, and just put an if-im-on-this-page-then-show-differently or inject another CSS. That's probably the easiest without any dev-know-how.
The harder, but possibly nicer way, is to actually to use a new template, and tell it to retrieve the items in the way they are configured in the other module - let's say module 1 is the original, module 2 has a different template wanting to access the items of module 1 in exactly the same order as given in 1. They way to do this is simple, but requires a few lines of C# code in Module 2.
You need to create a new ModuleDataSource (https://2sxc.org/en/Docs/Feature/feature/4542) object and tell it that it's from Module 1. If you've never done this, it's basically that your code can create a query just like the visual designer, but you have more control - see the wiki https://github.com/2sic/2sxc/wiki/DotNet-DataSources-All. The Module-Data-Source in the visual-query-designer doesn't allow you to "switch" modules (a advanced setting we may add in the future) but the object has a ModuleId property which you can set before accessing the data, making it "switch" to that Module. here's the Pseudo code in your Module#2 razor...
var otherModData = CreateSource<ModuleDataSource>();
otherModData.ModuleId = 1;
foreach(var itm in AsDynamic(otherModData["Default"])) {
...
}
That should do it :)

Why using the this.$(selector).method() syntax with backbone?

I have seen this bunch of code in a tutorial:
var searchTerm = this.$('#searchTerm').val().trim();
I would like to understand the utility of the this. in front of the selector, it's the first time i see that.
In a Backbone.View, this.$ gives a scoped version of jQuery. It is in fact equivalent to using this.$el.find which is in turn equivalent to using $(this.el).find.
Anyhow, the reason it is a good idea to use it is that it will only access html elements from within the view's element/rendered template. Thus, you don't have to worry about the rest of the html page and you will always select the element you expect to.
Imagine that you have a view that spawns sub-views and that each of these have an editable field. If you don't use the scoped version of jQuery to get the right editable field, you will have to give a unique id to each of these html elements to make sure you will select the right one when retrieving it's content. On the other hand, if you use the scoped version, you will just have to give this editable field a class attribute and selecting this class will give you a unique element, the right one.
This is the same query as this.$el.find('#searchTerm').val().trim();
You haven't given any context to that code, but assuming it's a method inside a View, this refers to the View object.
this.$ is a shortcut to access jQuery from the View object, and is equivalent to the method this.$el.find.

Render a page differently based on which list that opened it

I have two lists of different PageTypes - NewsItems and PressReleases. They are displayed in one list each, with links to the individual items.
Now I want to include the press release items into the news list and use the style of the news items to display them as news items. They share properties like "Heading" and "BodyText", which are used in the News Template.
I imagine that it won't be that difficult to feed the NewsItems' ListPage with both sets of pages, but I don't understand how I can control the rendering of the item page.
I would like to take the PageData object from a NewsItem OR a PressReleaseItem and display it using the News-Item.aspx template, if it is selected in a NewsList. But EPiServer will always render the PressReleaseItem with the PR-Item.aspx since it's coupled in the PageType settings.
Anyone know how to accomplish this?
EDIT: An effort to clarify:
The important issue is how to know the "list parent" and choose the right template from that. In the ListPage I can apply different looks on the PR and News items respectively using tompipes answer, but when selecting to see an individual item EPi will render the PR-Item-1 the same way regardless of their "list parent". That's the problem.
I'm not following exactly what you are attempting here. But I think I get the gist of it.
Why not use one aspx template for both page types, but in the code behind switch off sections using the visible attribute.
If you are using PageTypeBuilder you could use the "is" keyword:
somePlaceHolder.Visible = CurrentPage is NewsItemList;
If you're not using PTB, you could use something like:
somePlaceholder.Visble = CurrentPage.PageTypeID == 10;
or
somePlaceholder.Visble = CurrentPage.PageTypeName == "NewsItemList";
I'll point out now I'm not a fan of hardcoding anything, so I would place the template name, or ID into a config file, or a property on the start/root page to avoid hardcoding them.
Let me know if this will help, or if I have misunderstood please try elaborate on your issue.
Depending on how much the templates share you could go with user controls, placeholders or even different masterpages to switch view in a suitable way.
To know when to switch you could use a querystring parameter, session variable or the nicest looking way would probably be to lookup and get the list's PageData object by the HTTP referrer. If it's empty you will get press release rendering as the worst case.
I tried lots of solutions, including the adding of querystring to the PR items in the list links, the getting of referring url in the item template and different types of event hooking for automatic publishing of news items from a PR item (although I only looked at the code samples for that one), and finally came to the conclusion that they all had something that told me not to go that way. (Making the code too complex, or the markup logic too hard to understand and so forth)
I ended up using Fetch data from another EPiServer page, and creating a "shortcut pagetype" in which I let my editors pick which PR item should be used as base for a news item.
This shortcut pagetype is called "PR-as-news-itemPage" and it is rendered with the same aspx as ordinary news items: News-Item.aspx. Having no properties of its own, it will take all relevant data from the PR item selected with "Fetch..."
To render PR items with all its properties I created an ordinary new pagetype called PR-Item.aspx. This renders the "Attribute 2" property, which is only rendered by PR-item.aspx, and not by News-Item.aspx.
(I could have gone even simpler, by letting the editors use the old News-Item page type and use the "Fetch..." property there, but I have some mandatory properties in that page type which I didn't want to make optional for this sake.)

Count number of posts in cakephp

I'm trying to create a menu in cake php where I can also know how many articles are inside the section, should I use a manual query, or does exist some existing method to do it?
My site menu:
- Works (12)
- Photos (35)
- Stuff (7)
- Contacts
My problem is also I didn't get how I can access to data like this for every view, this should be a main menu, so I should use this in every view but If i put it in default.ctp, every model deosn't exist, because I cannot access it from a view.
Does exist some page which talks about this?
Since those are separate models that are not related to each other, you'll need to do a manual count.
$this->Model->find('count');
EDIT
Ok, so looks like you are talking about different models.
If this is used in a menu, that means it will be shown in all pages.
You have two ways of doing this.
You can do it by having an AppController for you application. Basically, you can put this code in the beforeRender method so it runs everytime your a request is rendered
function beforeRender() {
App::import('Model', array('Work', 'Photo', 'Stuff'));
$work = new Work();
$workCount = $work->find('count');
//do the same for the other
$this->set('workCount', $workCount);
}
Have a look at this for more details on callbacks : http://book.cakephp.org/view/977/Controller-Methods#Callbacks-984
Secondly, you can do this via a helper. You can put the same code (that is inside the bforeRender) into a helper, and you can call the helper method.
You can look here for more info on creating a helper : http://book.cakephp.org/view/1097/Creating-Helpers
The CounterCache behavior will help you out:
http://book.cakephp.org/view/1033/counterCache-Cache-your-count

How to get a value from a combobox in a form after the field is populated by the database

I have a formPanel with two of the form items as comboboxes with their stores populated by the database. The value from comboBoxA needs to be used to get the value for comboBoxB however comboBoxA.getValue() (as well as getRawValue()) are returning undefined.
storeA.load();
var comboBoxA = Ext.getCmp(comboBoxAID);
storeB.baseParams.UserID = comboBoxA.getValue();
storeB.load();
As noted in the docs, store loading is asynchronous, so you have to do your additional processing within the appropriate callback:
storeA.on('load', function(){
var comboBoxA = Ext.getCmp(comboBoxAID);
storeB.baseParams.UserID = comboBoxA.getValue();
storeB.load();
});
storeA.load();
Loading a ComboBoxes store does not actually select a value. Try making a selection first (or loading a record into the form, etc). It sounds like your trying to link the 2 combos. If thats the case, search around for a tutorial, there are few out there. This should get you started, Linked Combos.
You might want to try this. It might be exactly what you are looking for. It also has a demo on the same page. The page is in german but the demo is predictable and the code is in english so test this.

Resources