How to bind action only under certain condition [Ember.js] - ember.js

I just want to know, is there some way I can achieve the below purpose.
<button class="{{unless publishable "button-disabled"}}" {{if publishable (action "publish")}}>Publish</button>
Of course, it can be done in action method. I just think it could keep code drier if it can be done in template.
NOTE:
I know the code above will not work. It's only for purpose illustration.
I know button can use disabled attribute to achieve this. In my original work, it is actually a <a/> which doesn't have disabled. I need to keep it as <a/> tag for css purpose.
I wish to keep the button in page no matter it is disabled or not. This is kind of web page convention. In that case, user will know that he must missing something when the button is disabled.

It is possible using {{mut}} in combination with {{action}} helper:
<button {{action (if publishable 'publish' (action (mut undefProp)))}}>Publish</button>
Working demo.
You can read more about this specific use case (mut converts to function) in this blog post.
Explanation:
We use action helper and action which we pass to that helper will be computed - based on if condition.
If condition evaluates to true we return 'publish' which is simply action name.
If condition evaluates to false then we pass action which does nothing - we use something like workaround: (action (mut undefProp)).

Related

How to call child(`component`) method from parent?

How to call the child(component) method from parent(router) template?
I would like to know the ember recomended correct approach.
here is my try( i am directly calling not works!!)
Live demo on Twiddle
Because ember motto is Data down, Action up. Calling an action from child component is not meaningful.
But if it is suitable for your case, use it as contextual. Seen as shown this twiddle.
Such as:
{{#child-omponent as |actionHandler|}}
<footer>
<h3 onclick={{action actionHandler }}>Click me to called child components action</h3>
</footer>
{{/child-omponent}}

Simple search with Emberjs not working

I am trying to implement a simple search feature, which will filter the results and update the listing.
I tried almost every single tutorial out there, every tutorial seems to be working with its jsfiddle but when I apply the same thing on my project, it does not work at all.
Here is what I am having as a first problem, my search field does not seems to be bound with computed property in controller.
I also tried it as a component but again same issue, if I type anything in search field it does not reflect anything.
Let me share my code here,
input type="text" value=searchText placeholder="Search..."
searchResults: ( ->
console.log "On every key press it should come here.."
model = #get('model')
searchText = #get('searchText')
filterByPath = #get('filterByPath')
visualPath = #get('visualPath')
if searchText
searchText = searchText.toLowerCase()
model = model.filter(item) ->
Ember.get(item, filterByPath).toLowerCase().indexOf(searchText)>= 0
model.getEach(visualPath)
).property('searchText')
Tried almost the same thing with component, but no luck so far. I am not using handlebars but Emblemjs.
You actually need to use computed property in template if you want it to be compiled, then recompiled etc. It is somewhat lazily evaluated so you can't debug that without using this in template first or calling from JavaScript code. So basically you need to use searchResults in your template first.
In demo there was model instead of searchResults. I guess in your application you have similiar setup and same bug.
Fix:
{{#each searchResults as |item|}}
<li>{{item}}</li>
{{/each}}
Working demo.

How can I determine if a component returns nothing dynamically?

I have a ember component that is accessing a database and returning the results in a datatable type UI component. I would like to be able to use "N/A" when the result of the component is null or nothing.
For example, I have:
{{each bar in foobars}}
<td class="classyTD">
{{getBars bar=bar}}
</td>
{{/each}}
This works great when I have data, but returns nothing when I don't have data. The designers would prefer an "N/A". Modifying the database isn't an option and while modifying the component getBars is an option, it will be extremely painful.
Is there a method/way to handle this after the execution of the component? If not, or if it's a terrible idea - I'll suffer through changing the component, I trust the community's opinion.
You really should do this inside the component template. You can give the N/A string as a parameter, if that's of any help: http://emberjs.jsbin.com/lemabekuwi/2/edit?html,css,js,output
Or you could change the component that it indicates emptiness through a class and use some css magic: http://emberjs.jsbin.com/duqazahegi/1/edit?html,css,js,output
If you want to limit logic in the handlebars you can have the following in the component js file:
({
setBar: (function() {
if (!this.get('bar')) {
return this.set('bar', 'N/A');
}
}).observes('bar')
});

Django Crispy Forms - Add Button via Helper

I studied the Crispy-Forms documentation and I tried to put an extra button into one of my forms. With
self.helper.add_input(Button('back', "Back", css_class='btn'))
I can add a nice button. But the Button() wont take an onclick or on_click-attribute. So how can I add logic to this button? Adding an onclick event with JQuery isnt a very nice solution...
Thanks!
Ron
Are you certain that Button will not take onclick in its kwargs?
I just added an onclick="javascript here" to a Submit() element and it displayed fine.
I also peered a bit at the underlying code, and I think all inputs by default flatten the kwargs that aren't popped because of special use (i.e. template), and pass those through into the rendered HTML. This may be new since April '12 (when originally posted), but it currently seems to be as simple as the following:
self.helper.add_input(Button('back', "Back", css_class='btn', onclick="alert('Neat!');"))
This is not included by default (afaik..).
If you just need this once, is possible to use crispy-forms HTML Layout Object
HTML('<input type="button" name="Save" onclick="do_whatever" />')
What do you then dislike using jQuery? You could handle this rather easy and generic, using something like:
$('form :submit.ajax_submit').live('click', function(e) {
e.preventDefault();
var my_form = $(this).parents('form');
// do whatever
alert(my_form.attr('id'));
alert(my_form.attr('action'));
});
and then just pass the class:
Submit('save', 'save', css_class='ajax_submit')

Get the clicked submit button in a django form in a generic way

I have a finite state machine (django-fsm) which allows an object to go from a source state into one of several target states. I can add all the actions in a dictionary like:
ACTIONS { 'button_1': action1,
'button_2': action2,
...
}
This translates in a form with a submit button for each state.
{% for n,m in object.get_available_current_state_transitions %}
<input type="submit" class="btn" value="{{ n|get_action|capfirst }}"
name="button_{{n}}" />
{%endfor%}
<input type="submit" class="btn primary" value="Save">
<a class="btn" onclick="javascript:history.go(-1)">Cancel</a>
This usually results in more than 3 buttons.
Clicking a button results in a specific action, defined in my case in the model class.
Now, I know I can get the clicked button in the request.POST dictionary, but this would result in a cascade if like:
if 'button_1' in request.POST:
action_1()
elif 'button_2' in request.POST:
...
Is there any way to get the button pressed separately (ideally from the request object) in a variable so I can have something like
ACTIONS[clicked_button_name](...)
? In other words, is there any way to obtain the clicked button outside the POST dictionary?
PS: I've looked other replies on the "multiple buttons" question, but all offer request.POST as answer.
If all of the actions and strings are already in your view, why don't you just iterate over that actions dict?
for key, value in ACTIONS.items():
if key in request.POST:
value()
Just make your button names very unlikely to be used as a regular form field name.
A few alternatives: use javascript to handle the submission and have it set a single form field such as "action".
Use more unique keys and filter through request.POST.keys() with a regex pattern or string comparison.
action = [x for x in request.POST.keys() if 'FAIRLY_UNIQUE_BUTTON_PREFIX' in x]
if action:
ACTIONS[action]()
I don't think so directly, but a couple workarounds could be:
Send your buttons to different urlconfs with some variable (like a three letter arg). All of these confs point to the same view taking this three letter arg as an argument, which then knows what to do. This might still result in a cascade if else though.
Or, send them to different views all together.
You could try doing something ajaxy. The data will still be in a post dict, but you will have more control over how the post dict is structured.
I'm also assuming GET isn't an option for any of these (yet that still results in if else structures.)