My JSON has most of the time these two in its structure: "type" and "comments". Sometimes it has instead "type", "survey", "comments". So, I'd like to use "if" to let ext.xtemplate showing the ones it finds. For instance I've tried this but doesn't work:
new Ext.XTemplate(
'<div style="text-align:justify;text-justify:inner-word">',
'<b>Type:</b> {type}<br/>',
'<tpl if="survey">',
<b>Survey:</b> {survey}<br/>',
'</tpl>',
'<b>Comments:</b> {comments}',
'</div>'
I've tried instead these ones too but with no success:
<tpl if="survey != {}">
<tpl if="survey != undefined">
how could be the right way to detect an inexistent object?, thanks in advance.
PS. I'm using ExtJS 3.4
Use values local variable, for example:
var tpl = new Ext.XTemplate(
'<div style="text-align:justify;text-justify:inner-word">',
'<b>Type:</b> {type}<br/>',
'<tpl if="values.survey">',
'<b>Survey:</b> {values.survey}<br/>',
'</tpl>',
'<b>Comments:</b> {values.comments}',
'</div>'
);
Besides values there are also other variables available, which are helpful in some cases: parent, xindex, xcount.
Template after preprocesing is executed as a function, your template look like this:
function (values, parent, xindex, xcount){ // here are values, parent, etc
with(values){ // each property of values will be visible as local variable
return [
'<div style="text-align:justify;text-justify:inner-word"><b>Type:</b> ',
(values['type'] === undefined ? '' : values['type']),
'<br/>',
this.applySubTemplate(0, values, parent, xindex, xcount), // each <tpl> is converted into subtemplate
'<b>Comments:</b> ',
(values.comments === undefined ? '' : values.comments),
''
].join('');
}
}
This knowledge usually helps with understanding XTemplates.
Example usage of mentioned variables: http://jsfiddle.net/gSHhA/
I use <tpl if="!!survey>"
Related
I'm just starting with CodeIgniter and I can't output the value of my form_input. Here's my code:
<?= form_input('gender','','type="text" class="form-control form-input" value="'.foreach($profile as $prof){echo $prof->gender;}.'" disabled id="name" style="cursor:default"');?>
is my syntax even correct?
No, your syntax is not correct. Your arguments to form_input are wacky and, as you have it, only one input field is created. The "value" of that input might be something like
value='malefemalefemalemalemalemalsemalefemale',
Pretty sure that's not what you want.
Actually, from the code you post it's hard to know what you do want. My guess is this
<?php
//create an array with attribute values that don't change
$attributes = [
'class' => "form-control form-input",
'style' => "cursor:default",
];
//create a counter
$i = 0;
foreach($profile as $prof)
{
//inputs need a unique "name" and "id", use the counter for that purpose
$attributes['name'] = 'gender'.$i;
$attributes['id'] = "name".$i;
//add the 'value' of each profile to the array
$attributes['value'] = $prof->gender;
//send the array to form_input
echo form_input($attributes, NULL, 'disabled');
echo "<br>"; //new line
$i++; //increase value of counter by one for next loop run
}
The above will output a text field (each on a separate line) for each profile.
Documentation on `form_input'.
The "name" of the inputs will be "gender0", "gender1", etc, which will work. That is not the only way to do it. You could also use input arrays. That syntax is name='gender[]'. Either approach will work for the "name" but it won't work for the "id" attributes which must be unique.
The documentation seems to indicate that it is possible to nest custom components within other custom components (http://docs.ractivejs.org/latest/components) :
<Foo on-Bar.foo="barfooed" on-Baz.*="baz-event" on-*.bippy="any-bippy">
<Bar /><Baz /><Baz />
</Foo>
However, the following code only displays the tooltip. The inner custom components al-tt-translation, and al-tt-input are not initialized. In fact, replacing those two components by a string do not lead to that string being passed in anyway to the tooltip custom component .
tooltip = new Ractive({
el: 'airlang-rdt-tt-container',
template: "" +
"<al-tooltip>"+
" <al-tt-translation display='{{display_translation}}' translation_lemma='{{translation_lemma}}' result_rows='{{result_rows}}'/> " +
" <al-tt-input/> "+
"</al-tooltip>",
append: true,
components : {
'al-tooltip': Component_Tooltip,
'al-tt-translation' : Component_TT_Translation,
'al-tt-input' : Component_TT_Input
},
data : {
display_translation : 'block',
translation_lemma : 'example'
}
});
Should I conclude that it is not possible to use the custom tags in the same way than regular HTML tags?
Note : From the documentation, I understand that there is something to do with {{>content}} or {{>yield}} but I can't seem to make it work. What is the right way to do this?
For your example, your <al-tooltip> template needs to have either a {{yield}} or {{>content}} somewhere in it to direct where the contained content should go.
Simple example of how it works:
var Outer = Ractive.extend({ template: '<div>{{yield}}</div>' });
var Inner = Ractive.extend({ template: '<span>hello world</span>' });
var ractive = new Ractive({
el: document.body,
template: '<outer><inner/><inner/></outer>'
components: {
outer: Outer,
inner: Inner
}
})
produces:
<div><span>hello world</span><span>hello world</span></div>
{{yield}} means that the content still runs in the context in which it originated, {{>content}} means import the content as a partial and run it. In your example it probably won't matter because you're using components and not raw templates.
I'am using Extjs4.2.2. In my application i am using three loops, after the first loop i want to declare a variable and inside each iteration of second loop i want to increment the value and use the value in a class of a div. I have tried in the following way
'<tpl for="this.resources">',
'{% var parentIndex = xindex; %}',
'<tpl for="slots">',
'<div class="ext-cal-bg-row resource-slots-allocation tapaswini-'+(parentIndex++)+'" ></div>', // here i want to add the incremented value of parentindex to the class name tapaswini
'</tpl></tpl>',
But its giving error to me . Even am unable to access the "parentIndex" value.
Can anybody suggest where I'am missing. Any help is highly appreciated
Thanks in advance
Tapaswini
I found the solution
'<tpl for="this.resources">',
'{% var parentIndex = xindex; %}',
'<tpl for="slots">',
'<div class="ext-cal-bg-row resource-slots-allocation tapaswini-{[parentIndex++]} " ></div>',
'</tpl></tpl>',
By this am able to increment the variable
Thanks
Tapaswini
My teammates and I are learning AngularJS, and are currently trying to do some simple form field validation. We realize there are many ways to do this, and we have tried
putting input through validation filters
using a combination of controller and validating service/factory
a validation directive on the input element
a directive comprising the label, input and error output elements
To me, the directive approach seems the most "correct". With #3, we ran into the issue of having to communicate the validation result to the error element (a span sibling). It's simple enough to do some scope juggling, but it seemed "more correct" to put the span in the directive, too, and bundle the whole form control. We ran into a couple of issue, and I would like the StackOverflow community's input on our solution and/or to clarify any misunderstandings.
var PATTERN_NAME = /^[- A-Za-z]{1,30}$/;
module.directive("inputName", [
function () {
return {
restrict: "E",
require: "ngModel",
scope: {
fieldName: "#",
modelName: "=",
labelName: "#",
focus: "#"
},
template: '<div>' +
'<label for="{{fieldName}}">{{labelName}}</label>' +
'<input type="text" ng-model="modelName" id="{{fieldName}}" name="{{fieldName}}" placeholder="{{labelName}}" x-blur="validateName()" ng-change="validateName()" required>' +
'<span class="inputError" ng-show="errorCode">{{ errorCode | errorMsgFltr }}</span>' +
'</div>',
link: function (scope, elem, attrs, ngModel)
{
var errorCode = "";
if (scope.focus == 'yes') {
// set focus
}
scope.validateName = function () {
if (scope.modelName == undefined || scope.modelName == "" || scope.modelName == null) {
scope.errorCode = 10000;
ngModel.$setValidity("name", false);
} else if (! PATTERN_NAME.test(scope.modelName)) {
scope.errorCode = 10001;
ngModel.$setValidity("name", false);
} else {
scope.errorCode = "";
ngModel.$setValidity("name", true);
}
};
}
};
}
]);
used as
<form novalidate name="addUser">
<x-input-name
label-name="First Name"
field-name="firstName"
ng-model="firstName"
focus="yes"
model-name="user.firstName">
</x-input-name>
<x-input-name
label-name="Last Name"
field-name="lastName"
ng-model="lastName"
model-name="user.lastName">
</x-input-name>
...
</form>
First, because both form and input are overridden by AngularJS directives, we needed access to the ngModel API (ngModelController) to allow the now-nested input to be able to communicate validity to the parent FormController. Thus, we had to require: "ngModel", which becomes the ngModel option to the link function.
Secondly, even though fieldName and ngModel are given the same value, we had to use them separately. The one-way-bound (1WB) fieldName is used as an attribute value. We found that we couldn't use the curly braces in an ngModel directive. Further, we couldn't use a 1WB input with ngModel and we couldn't use a two-way-bound (2WB) input with values that should be static. If we use a single, 2WB input, the model works, but attributes like id and name become the values given to the form control.
Finally, because we are sometimes reusing the directive in the same form (e.g., first name and last name), we had to make attributes like focus parameters to be passed in.
Personally, I would also like to see the onblur and onchange events bound using JavaScript in the link function, but I'm not sure how to access the template markup from within link, especially outside/ignorant of the larger DOM.
I'm working on form validation and I have used Vtypes to check number ranges.
It's all working fine, except I need to include my own allowed values ( field.minValField and field.maxValField) in the 'numberrangeText'. Is there any way to do that ?
Thanks in advance
Ext.apply(Ext.form.VTypes, {
numberrange : function(val, field) {
if(val < field.minValField || val > field.maxValField){
console.log(field);
return false;
}
},
numberrangeText: 'Value Range Should Be: '
});
Arfeen
There is no way to use templates or XTemplates in numberrangeText. Because they(extjs) just take this string without changes as I've found out from file src/widgets/form/TextField.js from the line errors.push(this.vtypeText || vt[this.vtype +'Text']);.
But as you can see you can use field.vtypeText instead.
For example you can write something like this:
field.vtypeText = 'Value Range Should Be: ' + field.minValField + '-' + field.maxValField;
in your numberrange function.
You can see what I'm talking about in this example