i want to generate a list of data out of a store. each data item holds a title and a boolean. now i want to have a list of the items, each holding the title and a togglefield (showing the boolean) on the right of the title.
how could I do that?
thnx!
From the Sencha Touch documentation, a List is "a mechanism for displaying data using a list layout template", i.e. html template. If you want a 'list' of components, you'll have to make your own extension of DataView (I think).
A workaround could be to put an html checkbox inside your itemTpl.
Something like (warning - not tested):
itemTpl: '<p>{title}: <input type="checkbox" name="BoolCheckbox" class="boolcheckbox"'
+ "{[(values.bool? 'checked="checked"' : '')]}"
+ '></input></p>'
To run your own code in the XTemplate, you bracket it with {[]}. When in this scope, you have access to a variable 'values', which contains the data for the record.
To detect events, you'd add a listener to the list:
itemtap: function (dataView, index, item, e) {
if (e.getTarget().getClass().toString() == "boolcheckbox") {
// do something
}
}
Some resources on templates:
http://dev.sencha.com/deploy/touch/docs/
http://www.sencha.com/learn/xtemplates-part-i/
http://www.sencha.com/learn/xtemplates-part-ii/
Related
I am currently trying to implement an ember-drag-sort nested list into my Ember.js app.
Is there a way to determine in the dragEnd action which "sub-list" the item has been dropped into? (e.g. a class name, id etc)
In my scenario, I am sorting ember data records that can belong to each other (i.e. a nested, 'tree' structure). When I drag one nested record "into" another (making the dragged record a child of the second record), I need to update the parent attribute in ember-data. My question is, how do you pass some id of the second record (the new parent) to the dragEnd action?
Is this even possible?
EDIT:
To put it another way, I want to be able to identify which list I have dropped the item into.
targetList refers to the array on the dragged side of the component. For pushing the parent to the target list alongside the child, you can take a look at this twiddle.
To simplify identification of lists, the additional arguments feature has been implemented by #rwwagner90 (SO, GitHub).
You can pass some kind of list identifier into the additionalArgs argument to your lists. In this example I'm passing parent records which own the lists:
{{#each parents as |parent|}}
{{#drag-sort-list
items = parent.children
additionalArgs = (hash parent=parent)
dragEndAction = (action 'dragEnd')
as |child|
}}
{{child.name}}
{{/drag-sort-list}}
{{/each}}
In the dragEnd action you can access the parent records that own the source list and the target list:
dragEndAction({ sourceList, sourceIndex, sourceArgs, targetList, targetIndex, targetArgs }) {
if (sourceModel === targetModel && sourceIndex === targetIndex) return;
const item = sourceList.objectAt(sourceIndex);
sourceList.removeAt(sourceIndex);
targetList.insertAt(targetIndex, item);
// Access the parent via `sourceArgs` and `targetArgs`
sourceArgs.parent.save();
targetArgs.parent.save();
}
My code:
signup.emblem:
= validating-form onsubmit=(action 'signUp')
= input-field value=username
span {{usernameError}}
validating-form.js:
submit(event) {
console.log(this.get('username') //undefined
this.sendAction('onsubmit')
}
signup.js:
actions: {
signUp() {
console.log(this.get('username')) // value from input
}
}
As you can see the basic idea is some value in input gets validated in validating-form component and then if everything is fine it'll call some controller action or set some properties.
The problem is that apparently this form component isn't bind to properties from controller, even though its child component (input-field) is. Can you tell me what am I doing wrong here?
If I have to bind it explicitely, is there some way to do that with multiple properties at once?
The problem is that the standard input element isn't two-way bound to your username variable. You can bind it quickly using the action and mut helpers.
(example in handlebars, but you should be able to convert to emblem easily enough)
<input value={{username}} onblur={{action (mut username) value='target.value'}}>
This is saying:
on the onblur event
mut(ate) the username
to match the current target.value - which is the value of the input box
You can see evidence of this working in this twiddle
The other option is Input Helpers
I've not used these, as they don't follow the current Ember thinking of Data Down Actions Up, but it should be as simple as:
{{input value=username}}
And this will two-way-bind directly username.
In a .hbs file I am creating a navigation menu with various items. One of the items will only display if a user is a pro (boolean).
var pro is a variable set in my initializer and I need to pass it my .hbs file for the purposes of a conditionally showing one of the menu items.
In Ember, how is this accomplished?
In a such case, we use service to store variables during the application lifecycle. Initializer puts the variables and menu items to service. Menu components retrieve variables from service.
You may also define a helper to retrieve variable from service.
I had quite the same problem : I had to use a language variable that is set in my html and I needed to use this language variable in my template. I used a helper to do so : in the helper you can use the variable pro that is set in your initializer (provided you declared it).
example :
function myInit(pro) {
var template = ...;
var data = ...;
Handlebars.registerHelper('ifProUser', function(item) {
if (pro) {
return "pro menu here";
} else {
return "";
}
}
var html = template(data);
...
}
Then in the template just use :
{{ifProInit}}{{/ifProInit}}
I've got a spark list that is part of a CallOutContent, much like this:
<s:CalloutButton id="frequencyChanger" label="{frequencyChangeList.selectedItem.label}">
<s:calloutContent>
<s:BorderContainer>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:List id="frequencyChangeList" dataProvider="{Util.getFrequencyList()}" selectedIndex="8" requireSelection="false" changing="frequencyList_changingEvent(event)"/>
</s:BorderContainer>
</s:calloutContent>
</s:CalloutButton>
The dataProvider is an ArrayList with several items of the following structure:
public class ListItem
{
public var label:String;
public var item:Object;
public function PeriodFrequencyListItem(label:String, item:Object) {
this.label=label;
this.item=item;
}
}
The item Object is an Enum.
Background for this is to match the Enum to the corresponding label to be displayed in the List. I would have used a dictionary, but Lists don't work this those (unfortunately).
Anyhow, in the IndexChangeEvent method I can set the selectedItem to the one currently selected:
frequencyChangeList.selectedItem = event.currentTarget.selectedItem;
What I can't do (but desperately need in another part of the class) is to set the selectedItem of the List outside of the IndexChangeEvent method.
Any attempt to set an item with something like the following failed, throwing a null pointer exception.
frequencyChangeList.selectedItem = someListItemObject;
I can set the labels of the CallOutButtons, naturally, that doesn't change the selection of the List.
So, where is the trick to select an item in the list outside of its own 'changing' method?
Any help would be much appreciated.
Cheers!
Have you tried doing this:
myList.selectedIndex = indexOfArray;
see here:
How do I make sure that there is always something selected in a Spark List?
I need to put a search box within a list of objects as a result of a typical indexSuccess action in Symfony. The goal is simple: filter the list according to a criteria.
I've been reading the Zend Lucene approach in Jobeet tutorial, but it seems like using a sledge-hammer to crack a nut (at least for my requirements).
I'm more interested in the auto-generated admin filter forms but I don't know how to implement it in a frontend.
I could simply pass the search box content to the action and build a custom query, but is there any better way to do this?
EDIT
I forgot to mention that I would like to have a single generic input field instead of an input field for each model attribute.
Thanks!
I'm using this solution, instead of integrating Zend Lucene I manage to use the autogenerated Symonfy's filters. This is the way i'm doing it:
//module/actions.class.php
public function executeIndex(sfWebRequest $request)
{
//set the form filter
$this->searchForm = new EmployeeFormFilter();
//bind it empty to fetch all data
$this->searchForm->bind(array());
//fetch all
$this->employees = $this->searchForm->getQuery()->execute();
...
}
I made a search action which does the search
public function executeSearch(sfWebRequest $request)
{
//create filter
$this->searchForm = new EmployeeFormFilter();
//bind parameter
$fields = $request->getParameter($this->searchForm->getName());
//bind
$this->searchForm->bind($fields);
//set paginator
$this->employees = $this->searchForm->getQuery()->execute();
...
//template
$this->setTemplate("index");
}
It's important that the search form goes to mymodule/search action.
Actually, i'm also using the sfDoctrinePager for paginate setting directly the query that the form generate to get results properly paginated.
If you want to add more fields to the search form check this :)
I finally made a custom form using the default MyModuleForm generated by Symfony
public function executeIndex {
...
// Add a form to filter results
$this->form = new MyModuleForm();
}
but displaying only a custom field:
<div id="search_box">
<input type="text" name="criteria" id="search_box_criteria" value="Search..." />
<?php echo link_to('Search', '#my_module_search?criteria=') ?>
</div>
Then I created a route named #my_module_search linked to the index action:
my_module_search:
url: my_module/search/:criteria
param: { module: my_module, action: index }
requirements: { criteria: .* } # Terms are optional, show all by default
With Javascript (jQuery in this case) I append the text entered to the criteria parameter in the href attribute of the link:
$('#search_box a').click(function(){
$(this).attr('href', $(this).attr('href') + $(this).prev().val());
});
And finally, back to the executeIndex action, I detect if text was entered and add custom filters to the DoctrineQuery object:
public function executeIndex {
...
// Deal with search criteria
if ( $text = $request->getParameter('criteria') ) {
$query = $this->pager->getQuery()
->where("MyTable.name LIKE ?", "%$text%")
->orWhere("MyTable.remarks LIKE ?", "%$text%")
...;
}
$this->pager->setQuery($query);
...
// Add a form to filter results
$this->form = new MyModuleForm();
}
Actually, the code is more complex, because I wrote some partials and some methods in parent classes to reuse code. But this is the best I can came up with.