Ember button not staying disabled - ember.js

I have an ember form where the button is supposed to be disabled for the creation of the object. The first two forms I did this on worked fine, this one is giving me issues. The button is disabled but then renables before the controller action is done.
Goal: Prevent double click on the Create button from creating a duplicate object
I attempted to do this by disabling the button after the first click
View (just the button piece)
<button type="submit" class="btn btn-primary" type="submit" id="submit-attribute"{{action 'submit' newAttribute}} {{bind-attr disabled="isProcessing"}}>Create</button>
Controller (in CoffeeScript)
App.SpecificationNewAttributeController = Ember.ObjectController.extend
isProcessing: false
newAttribute: Ember.Object.create({
name: ""
datatype: ""
group: ""
})
datatypes: ['number', 'range', 'list', 'boolean', 'date']
actions:
submit: (content) ->
#set "isProcessing", true
specification = controller.get('content')
specId = specification.get('identifier')
revision = specification.get('revision')
specificationAttribute = #store.createRecord "SpecificationAttribute",
name: content.name
group: content.group
datatype: content.datatype
specification: specification
specificationIdentifier: specId
revision: revision
specificationAttribute.save().then ((specificationAttribute) =>
attributeId = specificationAttribute.get("id")
specification.get('specificationAttributes').addObject specificationAttribute
specification.save().then ((specification) =>
specification.reload()
groups = specification.get('specificationGroups')
group = groups.where(display_name: content.group)[0]
controller.transitionToRoute('specification', specification).then ->
$.growl.notice title: "Specification", message: "New Attribute Added"
)
#set "isProcessing", false
)

Answering this myself. It is a lame mistake but maybe it will help someone. I needed to move the #set "isProcessing", false into the inner save().then block:
actions:
submit: (content) ->
#set "isProcessing", true
controller = #controllerFor('specification')
specification = controller.get('content')
specId = specification.get('identifier')
revision = specification.get('revision')
specificationAttribute = #store.createRecord "SpecificationAttribute",
name: content.name
group: content.group
datatype: content.datatype
specification: specification
specificationIdentifier: specId
revision: revision
specificationAttribute.save().then ((specificationAttribute) =>
attributeId = specificationAttribute.get("id")
specification.get('specificationAttributes').addObject specificationAttribute
specification.save().then ((specification) =>
specification.reload()
groups = specification.get('specificationGroups')
group = groups.where(display_name: content.group)[0]
#set "isProcessing", false
controller.transitionToRoute('specification', specification).then ->
$.growl.notice title: "Specification", message: "New Attribute Added"
)
)

Related

Marking certain appointments as not selectable in Kendo Scheduler for ASP.NET MVC

I have the Scheduler loading multiple appointments. Some of those appointments should be read-only and the user should not be able to select them. Some of the appointments they should be able to select and edit, though. The logic for this is determined on the server and passed as a field in the payload on load.
I've attempted to hook into several client side events, such as Edit, MoveStart, and ResizeStart and cancel the edit events. This does work, however I would like the user to not even be able to select the event.
I do not see any client side events for Selecting that I can cancel.
I did attempt to iterate through the appointments on DataBound, but was unsure of how to prevent selecting at that point.
I suggest using a custom event template with and edit button and setting editable and selectable properties as false for the scheduler.
<script id="event-template" type="text/x-kendo-template">
<div>
<label>Title: #: title #<label>
# if (allowEdit) { #
<button style="margin-left:50px;" onclick="editSchedulerEvent(#:id#)">Edit</button>
# } #
</div>
<div>
Attendees:
# for (var i = 0; i < resources.length; i++) { #
#: resources[i].text #
# } #
</div>
</script>
<div id="scheduler"></div>
<script>
function editSchedulerEvent(id){
var scheduler = $("#scheduler").data("kendoScheduler");
var event = scheduler.dataSource.get(id);
scheduler.editEvent(event);
}
$("#scheduler").kendoScheduler({
date: new Date("2013/6/6"),
eventTemplate: $("#event-template").html(),
editable: false,
selectable: false,
dataSource: [
{
id: 1,
start: new Date("2013/6/6 08:00 AM"),
end: new Date("2013/6/6 09:00 AM"),
title: "Interview",
atendees: [1,2],
allowEdit: true
},
{
id: 2,
start: new Date("2013/6/6 10:00 AM"),
end: new Date("2013/6/6 11:00 AM"),
title: "Interview",
atendees: [3,4],
allowEdit: false
}
],
resources: [
{
field: "atendees",
dataSource: [
{ value: 1, text: "Alex" },
{ value: 2, text: "Bob" },
{ value: 3, text: "John" },
{ value: 4, text: "Jane" }
],
multiple: true
}
]
});
</script>
</body>
</html>

React-Rails: Use components with translations I18n

I have added to my project react-rails gem and I want to use for translated components.
I cannot put in the precompiled assets erb templates, but still I am trying to create components, make them available in all the project and then use them in some partial with some translation.
Working Scenario
# app/view/example/_react_component.coffee.erb
DOM = React.DOM
FormInput = React.createClass
displayName: "FormInput"
render: ->
DOM.div
className: 'row control-group'
DOM.div
className: 'form-group col-xs-12 floating-label-form-group controls'
DOM.label
htmlFor: #props.id
#props.label
DOM.input
id: #props.id
className: 'form-control'
placeholder: #props.placeholder
type: #props.type
DOM.p
className: 'help-block text-danger'
formInput = React.createFactory(FormInput)
window.ValidationFormInput = React.createClass
displayName: "ValidationFormInput"
getInitialState: ->
{ }
render: ->
formInput
id: "<%= t('validation_form.id') %>"
label: "<%= t('validation_form.label') %>"
placeholder: "<%= t('validation_form.placeholder') %>"
type: 'text'
validationFormInput = React.createFactory(ValidationFormInput)
# app/view/example/index.html.erb
<%= react_component('ValidationFormInput', {}, {class: "container"}) %>
Desired Scenario (not working)
# app/assets/javascripts/components/form_input.coffee
DOM = React.DOM
FormInput = React.createClass
displayName: "FormInput"
render: ->
DOM.div
className: 'row control-group'
DOM.div
className: 'form-group col-xs-12 floating-label-form-group controls'
DOM.label
htmlFor: #props.id
#props.label
DOM.input
id: #props.id
className: 'form-control'
placeholder: #props.placeholder
type: #props.type
DOM.p
className: 'help-block text-danger'
formInput = React.createFactory(FormInput)
# app/view/example/_react_component.coffee.erb
window.ValidationFormInput = React.createClass
displayName: "ValidationFormInput"
getInitialState: ->
{ }
render: ->
formInput
id: "<%= t('validation_form.id') %>"
label: "<%= t('validation_form.label') %>"
placeholder: "<%= t('validation_form.placeholder') %>"
type: 'text'
validationFormInput = React.createFactory(ValidationFormInput)
# app/view/example/index.html.erb
<%= react_component('ValidationFormInput', {}, {class: "container"}) %>
I guess that the issue is related to the scope of the definition of my component, but I cannot figure out how to make the component available for any partial.
Thank you in advance
Edit
In order to make the translations available, I found the gem I18n-js. After installing, I can easily run a rake task to create a js version of my config/locales/* translations
Excellent question.
There are a few ways to do this.
1- Usually, this is not just a question about how to pass data from Rails to React but rather how to generally pass data to Javascript. You can store the data in a meta in the header and access it from Javascript. This way you can still have your JS compressed and fast. (Instead of js.erb etc)
2- Passing all the translations to the react component. Basically, you can pass arguments to the react component, one of which is the translations. If it's a few translations, it's fine but if your list grows, the load would be heavy on your page.
3- Make your own Javascript translator. Here's a CoffeeScript example that I have created; make sure to add it in your assets' list before the other files.
In my code, I'm pulling the locale from meta (as you can see in the code). Feel free to edit this.
class Translator
#en = {
internet_connection_lost: "Your internet connection has been lost"
attempting_to_reconnect: "Attempting to reconnect!"
failed_to_reconnect: "Failed to reconnect..."
connection_success: "Connected"
reconnecting: "Reconnecting..."
bid_received: "Bid received. New balance $$bid_balance$$"
}
#ar = {
internet_connection_lost: "لقد فقدت الاتصال بالإنترنت"
attempting_to_reconnect: "نحاول إعادة الاتصال!"
failed_to_reconnect: "لم تنجح إعادة الاتصال بالشبكة..."
connection_success: "متصل بشبكة الإنترنت"
reconnecting: "إعادة الاتصال جارية..."
bid_received: "تم تلقي العرض. رصيد جديد $$bid_balance$$"
}
#get_translations: (locale) ->
switch (locale)
when 'en'
#en
when 'ar'
#ar
#translate: (val, interpolation) ->
# get locale from meta
locale = $("meta[name='locale']").attr("content") || "en"
translation = Translator.get_translations(locale)[val]
if interpolation
console.log "#{JSON.stringify(interpolation)}"
for k,v of interpolation
console.log "#{translation} : #{k} : #{v}"
translation = translation.replace(k, v)
return translation
window.Translator = Translator
And this is how you can use the Translator
message = Translator.translate(
"bid_received", { "$$bid_balance$$": 10 }
)

ember / ember-data belongsTo and hasMany not updating as expected

I have two models:
App.Focusarea = DS.Model.extend
definition: DS.attr('string')
theme: DS.belongsTo('theme',
async: true
)
App.Theme = DS.Model.extend
definition: DS.attr('string')
focusareas: DS.hasMany('focusarea',
async: true
)
when creating one of each, I would like to associate the focus area to that theme
theme = store.createRecord("theme",
id: 3
definition: 'theme definition'
)
focusarea = store.createRecord("focusarea",
id: 4
definition: 'focusarea definition'
)
theme.get("focusareas").then (focusareas) ->
focusareas.pushObject focusarea
theme.save()
but when I run my tests
theme.get('focusareas').then (focusareas)->
expect(focusareas.toArray.length).to.equal(1)
it fails - the focusareas.toArray.length equals 0, in other words, the association failed.
What am I doing wrong or what am I missing? Any help will be greatly appreciated.
Update:
Figured it out, theme.get('focusareas') returns an unresolved promise, which is 0, that when resolved will return 1 eg:
focusareas = theme.get('focusareas')
focusareas.then ->
console.log focusareas.get('length') #=1
or
store.find('theme', 4).then (theme)->
theme.get('focusareas').then ->
expect(theme.get('focusareas').get('length')).to.equal(1)
in other words
store.find('theme', 4).then (theme)->
theme.get('focusareas').then ->
theme.get('focusareas').forEach (item) ->
console.log(item.get('definition')) #'focusarea definition'
item.get('theme').then ->
console.log(item.get('theme').get('definition')) #'theme definition'
I guess I should just RTFM!
During object init you need to assign focusareas to some sort of collection that the getters and setters can work with . An ArrayProxy would work nicely in this case. How about even one you can sort items automagically with?
theme = store.createRecord("theme",
id: 3
definition: 'theme definition',
focusareas: Ember.ArrayProxy.createWithMixins Ember.SortableMixin,
content: [],
sortProperties: ['id'], // Set this to any object property
sortAscending: true
)
Hope that helped!

How to send a POST request from two different views?

This question is similar to my previous one: how to communicate with Rails in Ember but some things have changed. Now I know that a kudo is modelled in the server and has the following fields:
value
comment
It belongs to a user. The current implementation is as below:
<a href="#" class="btn btn-primary" {{action "addKudo" user}}>add</a>
Sks.ApplicationRoute = Ember.Route.extend
events:
addKudo: (user) ->
console.log event
self = #
token = $('meta[name="csrf-token"]').attr 'content'
currentUserCon = #controllerFor 'currentUser'
kudosLeft = currentUserCon.get 'kudosLeft'
showFlash = (type, message) ->
$("#flash")
.addClass(type)
.empty()
.append(message)
.show()
.fadeIn()
.delay(2000)
.fadeOut 'slow'
$.post("/kudos", user_id: user.get("id"), authenticity_token: token)
.done((data, status) =>
if kudosLeft > 0
currentUserCon.decrementKudos 1
showFlash 'alert-success', 'You\'ve added a kudo!'
else
showFlash 'alert-error', 'There\'re no kudos left!'
)
.fail (data, status) ->
showFlash 'alert-error', 'Oops! An error occured!'
But now, I'd like to make use of Ember-Data and send a POST request to /kudos (and I'd like to get rid of the jQuery ajax part). Please have a look:
Having the following model:
Sks.Kudo = DS.Model.extend
user: DS.belongsTo 'Sks.User'
value: DS.attr 'number'
comment: DS.attr 'string'
how can I achieve this? What are the neccessary steps to do this? Could anyone shed some light?
The next question is: where select and text area value should point to (bindings)?

Get text value passed to valueBinding in Ember.TextField (ember-validations)

I'm writing an extension to Ember.TextField to change the class of the text field if the parent object is invalid. I'm using the ember-validations library to do the validations on my ember-data object. I have this working right now, but I'd love to be able to do it without passing in the validationMethod variable. How can I get just the text string passed in to valueBinding from within the view?
address.js.coffee
App.Address = DS.Model.extend(Ember.Validations,
street_1: DS.attr('string')
street_2: DS.attr('string')
...
validations:
street_1:
presence: true
)
validated_text_field.js.coffee
Ember.ValidatedTextField = Ember.TextField.extend(
validationMethod: null
classNameBindings: 'error'
focusOut: ->
object = #get('controller').get('content')
object.validateProperty(#get('validationMethod'))
error: (->
object = #get('controller').get('content')
if object.get("isValid")
return false
else
error_keys = object.get("validationErrors." + #get('validationMethod') + ".keys")
if error_keys
return error_keys.length > 0
else
return false
).property('controller.content.isValid')
)
edit.handlebars
{{view Ember.ValidatedTextField validationMethod="street_1" valueBinding="street_1" id="street_1" placeholder="Street 1" required="true"}}
...
Although I can't suggest it because it's internal code, you can get the strings from the bindings themselves.
validationMethod = #get("valueBinding._from").split(".").get("lastObject")
Check out how we handle the label for Ember-Bootstrap for another example: https://github.com/emberjs-addons/ember-bootstrap/blob/master/packages/ember-bootstrap/lib/forms/field.js