Get the ID of a custom Control - custom-controls

I have a fairly complex Custom Control that may be used multiple times on any given XPage. In the control I create a couple of viewScope variables that have to be unique to the specific custom Control. I would like to do something like viewScope.put(customControlID + "variableName","Stuff)
But I don't know how to get the custom controls ID

You can get the current custom control ID with this.getId() at the <xp:view> level.
If you put this ID into a compositeData variable (e.g. compositeData.id) then you can use the ID inside the custom control everywhere you want.
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
beforePageLoad="#{javascript:compositeData.id = this.getId()}" >
Usage in SSJS:
viewScope.put(compositeData.id + "variableName","Stuff")
Typically, IDs are named like "_id2", "_id8", ...

You can use a dataContext variable:
<xp:this.dataContexts>
<xp:dataContext
value="#{javascript:this.getId()}"
var="id">
</xp:dataContext>
</xp:this.dataContexts>
The variable is then accessible as id in SSJS...
<xp:label id="label1" value="#{javascript:id}" />
... or in EL:
<xp:label id="label1" value="#{id}" />

Here is another solution as an SSJS function:
function getCCId( cmp:javax.faces.component.UIComponent):string{
try{
if( typeof( cmp ) === 'com.ibm.xsp.component.UIIncludeComposite' ){
return cmp.getId();
}
return getCCId( cmp.getParent() )
}catch(e){}
}
The function climbs the component tree until it finds the parent CC and then returns the id.
You can use it f.e. in a label like this:
<xp:label id="label1">
<xp:this.value><![CDATA[#{javascript:getCCId( this )}]]></xp:this.value>
</xp:label>

Related

External access to view elements created with createController and added to another view

I have a problem.
There is a view row.xml
<Alloy>
<View>
<Switch id = "search_switch" bindId = "search_switch" />
<Label id = "search_switch_label" />
</ View>
</Alloy>
And MAIN view
<View id = "general" bindId = "general ">
<Label id = "testLabel" />
</View>
When I adding
var control = Alloy.createController ('row');
Control.search_switch_label.text = 'TEST';
$.parent.add (control.getView());
All is perfectly added, but how to access the methods and properties of search_switch?
$.search_switch - says that "undefined"!!!
$.testLabel.text = '1234567890'; - All OK!
In your main view if you are trying to get the methods of row.xml, then you have two basic ways to do that :
1) Using the exports (in row.js)
var init = function (){
// some code here
}
exports.getInit = init;
2) Using the Alloy.Globals (in row.js)
Alloy.Globals.init = function(){
// some code here
}
Now to access the init function in Main View, you'll have to do the following respectively :
1) access exports function (in MainView.js)
var control = Alloy.createController ('row');
control.getInit();
2) access Alloy.Globals function (in MainView.js)
var control = Alloy.createController ('row');
if(Alloy.Globals.init)
Alloy.Globals.init();
Good Luck & Cheers
Firs thing as per your code is that when you use $, it means you are accessing the controls of the current controller so you can not use other controller's controls just by using $ sign. In your case, you need to set reference in you row.js file so you can access that controls or any variable or function in other controllers.
You need to do same as you did for search_switch_label. You can access search_switch object by control object in main.js like
control.search_switch.value

angular js template logic to remove repeater item

I have a repeater that looks like
<ion-item ng-repeat="obj in data">
{{obj.value}}
</ion-item>
which displays an item list of the numbers 1 through 10. When an odd number shows up I want that particular item to be hidden. Is this something I can do within the view it's self? Regardless what's a good way to do this?
You have to control your data set in your controller:
$scope.ProId = "";
$scope.HideOdd = function (){
-- create a function to hide DATA
}
and on your ion tag ad ng-hide="HideOdd"

Bind model to view from controller with alloy appcelerator

EDIT: Heres the example: https://github.com/prakash-anubavam/alloypreloadedsqlitedb/tree/master/app
And sumarizing, how does the view details.xml know which model is it taking the data from?
Coming from asp.net mvc, im having some issues understanding this MVC.
I can understand how to use tables and such on the view like:
<TableView id="table" dataCollection="fighters" onClick="showId" dataTransform="transformData">
And fetch the data in the controller, i know it will use the global (singleton) collection of fighters and that will bind the model to the view.
But i have come across an example (i cant really find now) where it had a View, with no table, just some labels and text='{variableName}', which i assume it gets from the model.
However the controller, did not assign the model (coming from an args[0] because it was always called from another controller which had the actual table), but it never assigned the model instance to the view in any way... so the question is how did it work? Is alloy smart enough to detect the actual model instance and use it? How would i do it? Something like $model = ...; or $.details.model = ...; or something like that? How did the view know where to take '{variableName}' from if the model was never assigned with a table or something.
This is actually a carryover hack, that may not work in the future, according to this thread.
If you take a look at index.js in your example (the controller), the model is assigned by the onClick event of the TableView:
function showId(e) {
if (e.row.model) {
var detailObj=fighters.get(e.row.model);
// Assigning to the $model actually sets this model as the one to bind too
var win=Alloy.createController('detail',{"$model":detailObj});
win.getView().open();
}
}
This is a "specai" variable that is automagically assigned for databinding, and is how it works underneath the covers (or did work under the covers).
This is undocumented and NOT ideal or recommended.
I've found Tony Lukasavage answer the cleaner aproach to bind a existing model to view:
You can find it here Josiah Hester answer is based on it (yeah, beware it's kind of a hack).
Although, Fokke Zandbergen gave an alternative worth looking at, maybe less hackish, don't know.
Expanding Josiah answer, you could do as follows:
On Master view:
<Alloy>
<Collection src="modelName" />
<View id="topview" class="container">
<TableView id="tblModels" dataCollection="modelName" dataTransform="transformModel">
<Require src="rowModel"/>
</TableView>
</View>
</Alloy>
Then, on master controller:
//retrieve the id of the model
var thisId = e.row.thisIndex;
//pass special key $model
var detailController = Alloy.createController("detail", { "$model": Alloy.Collections.detail.get(thisId) });
detailController.getView().open();
Then, on detail view:
<Alloy>
<View class="container" >
<Label text="{id}"/>
<Label text="{fullName}"/>
</View>
</Alloy>
On detail controller: do nothing special.
If you have a transform function on master controller, it returns a object and you can use its properties inside detail view like "{fullName}".

Where to define a filter function for a form field in my Joomla component's preferences

I am creating a component in Joomla 2.5. This component has some options that are defined in its config.xml, so they can be set in the preferences of the component. Now I would like to apply a filter to one of these option fields, using the attribute filter="my_filter".
In the source code of JForm I saw the following lines at the very end of the implementation of JForm::filterField():
if (strpos($filter, '::') !== false && is_callable(explode('::', $filter)))
{
$return = call_user_func(explode('::', $filter), $value);
}
elseif (function_exists($filter))
{
$return = call_user_func($filter, $value);
}
That's what I needed for using a filter function defined by myself!
I managed to do this for form fields used in the views of my component. I defined the filter function as MyComponentHelper::my_filter(), where MyComponentHelper is a helper class which I always load in the very base of my component. And in the form's xml I added filter="MyComponentHelper::my_filter" to the fields that have to be filtered. However... when I am trying to apply the filter function to a form field in my component's preferences, I am not in my own component, but in com_config instead, so my helper class is not available!
So, therefore, my question: where to define my own filter function in such a way that it can be found and called by JForm::filterField() in com_config?? Help is very much appreciated.
May be it is too late, but this topic is only I found about that trouble. May be my solution will be helpfull to someone.
1) Add to tag of .xml form file the attribute 'addfieldpath' like this:
<fieldset name="basic" addfieldpath="PATH_TO_MY_EXTENSION/models/fields">
2) Modify filtered field description like this:
<field
name="MY_FIELD_NAME"
type="myfildtype"
label="MY_FIELD_LABEL"
description="MY_FIELD_DESC"
filter="JFormFieldMyFieldType::filter"
/>
3) Create the file 'PATH_TO_MY_EXTENSION/models/fields/myfildtype.php':
<?php
defined('JPATH_PLATFORM') or die;
JFormHelper::loadFieldClass('text'); // or other standard Joomla! field type
class JFormFieldMyFieldType extends JFormFieldText // or other standard Joomla! field type class
{
protected $type = 'MyFieldType';
public static function filter($value)
{
// filter code
return $value;
}
}
I had to deal with the same issue today. Here is what I did.
Our form field looks like this:
<field name="verwaltungskosten" type="text" class="form-control" size="40" label="Verwaltungskosten" labelclass="col-sm-2
compojoom-control-label"
filter="MyComponentFilterDouble::filter" required="true"/>
As you can see we have a filter. We've specified
MyComponentFilterDouble as class and filter as a method of this class.
If you have a look at libraries/joomla/form/form.php in the
FilterField function toward the end you'll see that the code will try
to execute our custom filter. Now here comes the tricky part. How does
Joomla know where our filters are located? Well, it doesn't! We have
to load our filters in advance. JForm doesn't come with a utility
class that could load a custom filter. I've decided to load our
Filters in our model in the getForm function. As you know each model
that extends from JModelAdmin should have a getForm function. This
function makes sure that we are loading the correct form from a .xml
file. So in this function just before I load the form I did:
JLoader::discover('MyComponentFilter', JPATH_ADMINISTRATOR . '/components/com_mycomponent/models/forms/filters');
The discover method will make sure to auto load our class when we need
it. This way it will be available to our form.
And there we go! Now when our model validates the form. It actually
always first performs filtering on the data. Now in our custom filter
we can modify the data and pass it back for validation. It's that
easy!
The above text is in quotes because I took it from my blogpost about that same issue over here: https://compojoom.com/blog/entry/custom-filtering-for-jform-fields
I think what you're asking about is actually adding custom validation to one of your form fields. If that's the case you actually need to be looking at adding server-side validation in addition to adding configuration. Pay particular attention to the 'addrulepath' in the example under the heading "Using configuration parameters as default value". You'll most likely end up extending JFormRule, of which I've included a very stripped-down example below.
<?php
/** headers */
defined('JPATH_PLATFORM') or die; // Joomla only
class JFormRuleCustom extends JFormRule
{
public $type = 'Custom';
public function test(&$element, $value, $group = null, &$input = null, &$form = null) {
return /* true for passed validation, false for failed validation */
}
}
When you've got that down you can add the validation "custom" to your form fields like so:
<field
name="pw1"
type="password"
label="COM_NEWUSER_UPDATE_LABEL_PASSWORD1"
description="COM_NEWUSER_UPDATE_DESCRIPTION_PASSWORD1"
message="COM_NEWUSER_UPDATE_ERROR_PASSWORD1"
size="40"
required="true"
validate="custom"
minlength="5"
maxlength="20"
specials="!##$%^&*"
/>
Hopefully that answers your question and didn't go totally off-topic.

Form select box in Backbone Marionette

I'm trying using Backbone.Marionette to build an application. The application gets its data through REST calls.
In this application I created a model which contains the following fields:
id
name
language
type
I also created an ItemView that contains a complete form for the model. The template I'm using is this:
<form>
<input id="model-id" class="uneditable-input" name="id" type="text" value="{{id}}"/>
<input id="model-name" class="uneditable-input" name="name" type="text" value="{{name}}" />
<select id="model-language" name="language"></select>
<select id="model-type" name="type"></select>
<button class="btn btn-submit">Save</button>
</form>
(I'm using Twig.js for rendering the templates)
I am able to succesfully fetch a model's data and display the view.
What I want to do now is populate the select boxes for model-language and model-type with options. Language and type fields are to be restricted to values as a result from REST calls as well, i.e. I have a list of languages and a list of types provided to me through REST.
I'm contemplating on having two collections, one for language and one for type, create a view for each (i.e. viewLanguageSelectOptions and viewTypeSelectOptions), which renders the options in the form of the template I specified above. What I am not sure of is if this is possible, or where to do the populating of options and how to set the selected option based on data from the model. It's not clear to me, even by looking at examples and docs available, which Marionette view type this may best be realized with. Maybe I'm looking in the wrong direction.
In other words, I'm stuck right now and I'm wondering of any of you fellow Backbone Marionette users have suggestions or solutions. Hope you can help!
Create a view for a Select in my opinion is not needed in the scenario that you are describing, as Im assuming that your languages list will not be changing often, and the only porpouse is to provide a list from where to pick a value so you can populate your selects in the onRender or initializace function of your view using jquery.
you can make the calls to your REST service and get the lists before rendering your view and pass this list to the view as options and populate your selects on the onRender function
var MyItemView = Backbone.Marionette.ItemView.extend({
initialize : function (options) {
this.languages = options.languages;
this.typeList = options.typeList;
},
template : "#atemplate",
onRender : function () {
this.renderSelect(this.languages, "#languagesSelect", "valueofThelist");
this.renderSelect(this.typeList, "#typesSelect", "valueofThelist")
},
renderSelect :function (list, element, value) {
$.each(list, function(){
_this.$el.find(element).append("<option value='"+this[value]+"'>"+this[value]+"</option>");
});
}
})
var languagesList = getLanguages();
var typeList = getTypesList();
var myItemView = new MyItemView({languages:languagesList,typeList :typeList });
Hope this helps.

Resources