Ember: concat attributeBinding, how to? - ember.js

I need to concat several variables to create one attribute, for an example I have a set of RadioButtons which may appear several times on the page - dynamically, first the view can be displayed severl time, other thing is that they are placed in each loop so they can appear several times per view.
So I can't use static name attribute, but I should concat if with several parts, for an exampe result should look like:
<input name="view1_row0" value="0"> No
<input name="view1_row0" value="1"> Yes
<!-- next row in view1 -->
<input name="view1_row1" value="0"> No
<input name="view1_row1" value="1"> Yes
<!-- next row in view2 -->
<input name="view2_row0" value="0"> No
<input name="view2_row0" value="1"> Yes
etc... I can easily get the parent's view's ID and/or index of the loop with view._parentView.contentIndex but I have no idea how to concat them in one binding, the pseudo code would look like this:
{{view Ember.RadioButton nameBinding=view.parentView.elementId + "_row" + view._parentView.contentIndex selectionBinding="someVal" value="0"}}
But it of course throws the error at + sign. Is there any way to resolve that ?

Why not pass them in as separate bindings and the concatenate them in a custom implementation of Ember.RadioButton?
{{view App.MyRadioButton elementIdBinding="view.parentView.elementId" contentIndexBinding="view._parentView.contentIndex" selectionBinding="someVal" value="0"}}
and then in App.MyRadioButton (which extends Ember.RadioButton)
name: function() {
return this.get('elementId') + '_row' + this.get('contentIndex');
}.property('elementId', 'contentIndex')
Alternatively you might also be able to do that in your controller.

Related

Salesforce lightning Input with list doesn't work

I'm trying use input with datalist in a lightning component and doesn't seem to work. I've looked around and can't seem to find anything that says i can't. So basically,
<input list="acctlist"/>
<datalist id="acctlist">
<option value="somevalue">
</datalist>
does not work. I want to have an input in a form that a user can type but also able to select from a list returned from the controller. Is there a workaround that would be as simple or is this the following route the best i got.
https://developer.salesforce.com/blogs/developer-relations/2015/06/salesforce-lightning-inputlookup-missing-component.html
The list attribute of input tag is not compatible with lightning component.
When you deploy the components, the attribute is removed.
If you want to use input with datalist, you need to add the attribute in Renderer.js.
datalist.cmp
<input aura:id="acctlistInput" />
<datalist id="acctlist">
<option value="somevalue" />
</datalist>
datalistRenderer.js
afterRender : function(component, helper) {
var acctlistInputCmp = component.find("acctlistInput");
var acctlistInput = acctlistInputCmp.getElement();
acctlistInput.setAttribute("list", "acctlist");
return this.superAfterRender();
}

how to set two class name for Ember.js input helper

i'm trying to bind an input element like this:
{{input value=email type="text" placeholder="Enter email" class=emailError:with-error}}
it works just fine, as long as I try to assign it only 1 class name ".with-error".
how can I assign 2 class names, so it will be: ".with-error .second-class"?
I know how to do it with:
{{bind-attr class=":secondClass emailError:with-error"}}
but this doesn't work with input helper.
Thanks!
This feature is not well documented, but when defining attributes on a Handlebars helper, you can either leave out the quotes to indicate that you want the value of the attribute to be a bound variable, or you can add the suffix "Binding" and then use quotes with an expression similar to the one you would use with {{bind-attr}}.
So, in your case, the following should work:
{{input value=email type="text" placeholder="Enter email" classBinding="emailError:with-error :myClassName"}}
Note how instead of class=myBoundValues we are using classBinding="myBoundValue".

Setting html-attributes in Handlebars/emberjs?

I'm trying to set html-attributes in handlebars in an emberjs application.
<input type="{{field.type}}" name="{{field.key}}" id="{{field.name}}" />
is what I attempted.
It will outpup html like this:
<input type="<script id='metamorph-13-start' type='text/x-placeholder'></script>text<script id='metamorph-13-end' type='text/x-placeholder'></script>" name="<script id='metamorph-14-start' type='text/x-placeholder'></script>entry.810220554<script id='metamorph-14-end' type='text/x-placeholder'></script>" id="<script id='metamorph-15-start' type='text/x-placeholder'></script>firstname<script id='metamorph-15-end' type='text/x-placeholder'></script>">
All tags are wrapped in metamorph-tags. I expect this isn't what you are suppose to do. How can I add attributes based on my model.
Use bind-attr when you are binding to an element attribute
<input {{bind-attr type=field.type name=field.key id=field.name}} />

Tabular form validation without submitting

In APEX 3.2, I want to be able to run JavaScript validations to check the data entered and display the appropriate message above each row in the tabular form.
I'm not sure how this would work given that it is a tabular form and the user will be able to add/delete rows.
Appreciate any ideas or suggestions.
Thanks.
Okay, doing some javascript validations on tabular forms is a bit complex, and you need to know what you're doing.
First off, you will need to know the ids or names of the elements you wish to check. As you may know, elements in tabular forms are stored in arrays in apex on submit, and are accessed through apex_application.g_f01/g_f02/...
This is reflected in the html code, and the generated elements also have the attribute 'name' set to the column they belong to. The id also holds the column, plus the rowindex. Warning though, this id is only generated like this when the item is created 'implicitly', ie you did not write your query with apex_item calls (apex_item.textbox(...)).
Another but is that only fields of which the state is saved will have an array column defined. An item which you'd only show as 'display only', will not be generated with an input tag, and will just be held as text in a td tag.
All by all, when you know that, the next steps should be straightforward enough. Take a look at the page source, and take a note of the elements you wish to target. For example, i went for the job field.
<tr class="highlight-row">
<td headers="CHECK$01" class="data"><label for="f01_0003" class="hideMeButHearMe">Select Row</label><input type="checkbox" name="f01" value="3" class="row-selector" id="f01_0003" /></td>
<td headers="EMPNO_DISPLAY" class="data">7782</td>
<td headers="ENAME" class="data"><label for="f03_0003" class="hideMeButHearMe">Ename</label><input type="text" name="f03" size="12" maxlength="2000" value="CLARK" id="f03_0003" /></td>
<td headers="JOB" class="data"><label for="f04_0003" class="hideMeButHearMe">Job</label><input type="text" name="f04" size="12" maxlength="2000" value="MANAGER" id="f04_0003" /></td>
<td headers="HIREDATE" class="data"><label for="f05_0003" class="hideMeButHearMe">Hiredate</label><span style="white-space: nowrap;"><input type="text" id="f05_0003" name="f05" maxlength="2000" size="12" value="09-JUN-81" autocomplete="off"></span></td>
<td headers="SAL" class="data">
<label for="f06_0003" class="hideMeButHearMe">Sal</label><input type="text" name="f06" size="16" maxlength="2000" value="2450" id="f06_0003" />
<input type="hidden" name="f02" value="7782" id="f02_0003" />
<input type="hidden" id="fcs_0003" name="fcs" value="19BD045E01D6BA148B4DEF9DDC8B21B7">
<input type="hidden" id="frowid_0003" name="frowid" value="AAuDjIABFAAAACTAAC" />
<input type="hidden" id="fcud_0003" name="fcud" value="U" />
</td>
</tr>
In the javascript section of the page i then added the following 2 functions.
validate_job does the validation of just one field, the element elJob. The validation i used is just very basic, it's up to you to determine just how complex you want it.
If you want to reference other fields in the same row here, you can do several things: extract the rowindex from the id, if you have it. If it doesn't hold the it, get the parent TR, and then use .children("input[name='f##'") to get an input element in the same row. Or if you need the value of an item which does not save state at all, you'll need to get the TR element, and then find the TD which contains the element you need through the headers attribute, which holds the column name.
function validate_job(elJob){
var sJob = $v(elJob).toUpperCase();
$(elJob).val(sJob);
//do your validations for the field job here
if(sJob=="MANAGER"){
$(elJob).css({"border-color":"red"});
alert("invalid value!");
//depends what you want to do now:
//keep the focus on this element? Set a flag an error occured? Store the error?
return false;
} else {
$(elJob).css({"border-color":""});
alert("value ok");
};
};
Call bind_validations onload. If you allow rows to be created, bind a click event to the addrow button and call bind_validations.
function bind_validations(){
//f01 : row selector
//f03 : ename
//f04 : job
//f05 : hiredate
//f06 : sal
//each input element with attribute name with value f04
//blur event is when the user leaves the field, fe tab out, or even click apply changes
//much like how when-validate-item behaved in forms
$("input[name='f04']").blur(function(){validate_job(this);});
};
Just a proper warning though. I've used javascript validations in some apps so far, but i knew they were only going to be used by a small number of people, and then only internally. It was only one field, with some validations. I made the cursor refocus on the field when the validation failed, so they couldn't jump to the next record and change that aswell. Either a valid value was given, or they reloaded the page or canceled the action. Set up like this, they can't press apply changes either, as the blur event would also fire, validating the field.
When your audience is larger, it gets a bit more iffy: what i javascript is disabled? What if they find some way around? Wizzkids?
I still like the immediate feedback it gives, but in a more critical environment i'd also use the server-side validations. To do this, you need a validation of the type "function returning error text". Check out this page for an example, or this one for some usefull tips (at least for pre 4.0!). Also: apex 4.1 really improves a lot on tabular form validations! ;)

What is the best practice to create array notation fields in play-framework templates?

In one of my Play! projects I use a table of inputs to update multiple objects in one go.
I pass it to the controller as an array of objects. This works quite well, but the template looks quite a mess, since I'm forced to write the whole array index notation.
The template in its current state:
#{list items:_articles, as:'article' }
<tr>
<td>${article.number}</td>
<td>${article.name}</td>
<td>${article.totalPrice}</td>
<td><input type="text" name="${ 'articles[' + article_index + '].description'}" value="${article.description}" /></td>
<td>
#{select 'articles[' + article_index+ '].consignment', value:article.consignment}
#{option ''} -- #{/option}
#{option 'Foo'} Foo #{/option}
#{option 'Bazz'} Bazz #{/option}
#{option 'Bar'} Bar #{/option}
#{/select}
<input type="hidden" name="${ 'articles[' + article_index + '].id'}" value="${article.id}" />
</td>
</tr>
#{/list}
What - if there is one - is the best-practice to create array-notation fields using the play-framework?
Create a seperate variable for the 'articles[' + article_index + '] inside your loop?
Or; Maybe you just can leave it out? Create an array without your article index:
<input type="hidden" name="article.id[]" />
<input type="text" name="article.name[]" />
Later on, in your loop you can figure out the array index, and the corresponding id. Problem is you can't have optional fields this way. I won't recommend it.