How to override some styles only inside another component - css-modules

I have React component with own styles. And i have to change styles for this component in another place, component etc. How i can get and use classnames?
1) My Alert component styles. (classname will change to some hash)
alert styles pic
2) My UserAuth component styles (classnames also will change to some hash)
auth form styles pic
So how to get .alert classname hash in user auth styles and use it.

Related

Is it possible to have Livewire events in a Datatables render function

I'm trying to open a modal and populate a form field with a model value.
The button to open the modal is embedded in the datatable config js and I'm thinking Livewire is running before the table is built.
The datatable uses ajax to populate and columnDefs to configure rows.
The JS for the config of the datatable is in a #push('scripts') in the component blade file.
The (simplified) render function for the row is:
var datatable = thetable.DataTable({
.....
render: function (data, type, full, meta){
return ('Edit');
},
.....
})
Clicking the button opens the modal but no XHR is made to the components edit function.
If I create an anchor in the same blade file as "normal" html:
<a href="#" wire:click="edit({{ 25 }})">test</button>
The XHR is called as expected.
So, I'm assuming Livewire doesn't know about the button - perhaps it ran before the table was built. Is there a way to force Livewire to wait?
I have tried to emit a Livewire event instead of wire:click = also no XHR.
I have seen the couple Laravel packages for Datatables. They don't suit.
I got this done with emitted events and component listeners.
jQuery's on to bind to the future elements clicks which livewire.emit the events.
protected listeners[] in the component respond to the emitted events.

force re-render of custom textfield view

How to force to re-render a custom textfield view?
I create a:
App.Select2View = Ember.TextField.extend({didInsertElement:function() {//plugin called here}});
It's included in a template form and when the form is open and I select another/different item, this custom textfield view (based on select 2) doesn't re-render but stays the same.
I have nested routes/resources. Company under companies. When I select a company I have readonly info and edit button that if clicked calls action on the Company controller to "isEditing" state, in this state a form is open. If I change the state to false it goes back into read only model (viewing the company info).
It's fine if I set it back to read only mode first, and then open another item and the select2 is rendered with this companies data.
But if it's in the isEditing state, with form open and I navigate to another company item all form input fields change according to model (such as name will change because it's binded to the name key value of the company model), but the select2 stays the same as previous.
I'm not sure how to re-render this in Ember.
This is defined as partial in template under the main company template view:
<script type="text/x-handlebars" id="company/_edit">
<p>{{input type="text" value=name}}</p>
<p>
{{view "select2"
prompt="Search for companies"
resource="results"
displayKey="text"
onSelect="addCompany"
onDeSelect="removeCompany"
}}
</p>
</script>
Any pointers are appreciated.
I'm new to Ember and my answer might not be apt, but based on my experiments the problem is that Ember caches as much as possible. So it won't re-render the view completely with the select2, only when view is in a certain state previous state followed by next state will it automatically re-render.
The solution atleast for now seems to be to add a "valueChange" method with observer on "value" change on the select2 custom TextField and make the same call as in "didInsertElement" (which executes when the view is rendered):
valueChange: function() {
Ember.run.scheduleOnce('afterRender', this, 'setupSelect2');
}.observes('value'),
Now even if I'm in the "edit" state, it will update this select2 as well, not just the standard form inputs tied specifically to the model. I can now navigate to any item in "edit" state which has form open for each item selected and values change correspondingly in the select2.

Ember Component keyboard events

In my webapp I have a search field at the top (kinda like Facebook) which is an input field and a bootstrap dropdown for result suggestions. I would like to decouple it from the controller of its container into an Ember Component. But I don't understand how to pick up events from the input field. Right now the view picks up submit (there is no submit button) and keyUp/keyDownfor navigating the dropdown. How do I listen to these events on a Component?
You can use Component the same way as you would View.
App.SearchFieldComponent = Ember.Component.extend({
value: "",
keyUp: function (e) {
console.log(e);
alert("You pressed key code " + e.keyCode);
}
});
Full jsbin.

binding controller object to a component in ember

I am trying to build a modal box component in ember. The modal box has two standard buttons, "close" and "save". I wanted to pass controller action to this component so that when save button is clicked, it calls the controller action that was passed. I call my component as :
{{#affi-modal-box title="Test title" modalId="createNewAnalyticsRunModal" controllerBinding=controller}}some message{{/affi-modal-box}}
and my component :
AS.AffiModalBoxComponent = Ember.Component.extend({
attributeBindings: ['modelId','test'],
//this is the function that gets called when save button is clicked
onSaveButtonClick : function(){
console.log(this.controllerFor('analysisTemplates'));//fails
console.log(this.get('controller'));//returns modal box component which I don't need
}
});
Any ideas how I can pass the controller object to the component??
Thanks.
The way Ember.Component's work is to be agnostic to other parts of your application, therefore rather then passing in a controller on which you want an action to be called on when something happens in your component, you do it more like in this way:
{{#affi-modal-box
title="Test title"
modalId="createNewAnalyticsRunModal"
action="actionNameOnTheController"}}some message{{/affi-modal-box}}
As you can see you set the action attribute to the action name on your controller, and then inside your component you simply call this.sendAction('action'); which will trigger whatever action name you defined earlier:
AS.AffiModalBoxComponent = Ember.Component.extend({
attributeBindings: ['modelId','test'],
//this is the function that gets called when save button is clicked
onSaveButtonClick : function(){
this.sendAction('action');
}
});
So now, whenever onSaveButtonClick is invoked it will send the action actionNameOnTheController to whatever controller is listening to it. And best of all, without knowing nothing about the controller. This is the kind of functionality that makes Ember.Component's reusable in any way.
Please see here a simple demo of the concept explained.
Hope it helps.

inline javascript within handlebars template

Is there no way to have an inline script within a Handlebars template?
<script type="text/x-handlebars">
I'm a row of type "foo"
<script type="text/javascript">alert('hi');</script>
</script>
When the above template renders, the inline script is removed.
What I am trying to do is include the disqus widget on a page. The widget is basically some markup + disqus script.
The widget is to be included within a sub-view of my app. The subview is not visible by default but is displayed as per some logic in my Ember app code.
​
You'll have to wrap that widget in a custom Ember.View to handle instantiating it and adding it to the DOM, in the wrapper view's didInsertElement. Ember expects, especially inside handlebars templates, to have full control over DOM manipulation, and it does that with a combination of handlebars magic, and Ember.View creation. Once you've defined your customview:
MyApp.DisqusView = Em.View.extend({
didInsertElement: function() {
// create widget and append it to this.$()
}
});
You can use it in your handlebars template:
{{view MyApp.DisqusView}}
Your view should not add Script tags, for safety reasons, but should rather execute any JS directly to insert the widget.