Appcelerator - Add widget into tableviewrow - appcelerator

I have a tableView and I want to add a widget into a tableViewRow by code in the js file.
My widget is called: "es.comboBox" (I'm using it in other controllers and it works perfectly, but I'm creating it at xml file).
This is my code:
index.xml
...
<TableViewRow id="row_subseccion" layout="vertical"</TableViewRow>
...
index.js
var widget = Alloy.createWidget("es.comboBox", {
choices: subsecciones,
value: -1
});
$.row_subseccion.add(widget);
The error is: (The error appears when the program is executing the add instruction)
libc: Fatal signal 11 (SIGSEGV) at 0x76616a64 (code=1), thread 5058
(KrollRuntimeThr)
What I'm doing wrong? Thank you.
This works, but I need to add it after an action from the user.
<TableViewRow id="row_subseccion" layout="vertical">
<Widget src="es.comboBox" class="selectField" id="subseccion"></Widget>
</TableViewRow>

The widget var holds the actual Alloy Controller of the widget, not the view you can add to the row. Please change to:
$.row_subseccion.add(widget.getView());

Related

Making focus works inside a CK Editor 5 createUIElement

So I've a custom widget which renders a custom component.
conversion.for('editingDowncast').elementToElement({
model: 'modelName',
view: (modelElement, viewWriter) => {
const modelName = modelElement.getAttribute('modelName');
const modelNameView = viewWriter.createContainerElement('span', {
class: 'modelName',
'data-modelName': modelName,
});
const reactWrapper = viewWriter.createUIElement(
'span',
{
class: 'modelName__react-wrapper',
},
function (this, domDocument) {
const domElement = this.toDomElement(domDocument);
rendermodelName(modelName, domElement);
return domElement;
},
);
viewWriter.insert(
viewWriter.createPositionAt(modelNameView, 0),
reactWrapper,
);
return toWidgetEditable(modelNameView, viewWriter);
},
});
Where rendermodelName will give back a React component with a simple input box as
return (
<div>
<input type="text" />
</div>
);
https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/react.html.
But the problem is, whenever I tried to add some content inside the input, the focus is lost from the field and automatically moved to the surrounding editor. What am I missing. Tried creating a focushandler and adding the modelNameView to it.
Should I go with the new createRawElement? My current CK5 is 20.0.0 So I don't want any breaking changes coming now.
EDIT:
I researched a little bit more. seems like createRawElement may not work here. I think this doesn't have a simple solution. I tried with allowContentOf: '$block' which also not letting me focus. But these values are explicitly for normal CK widget, not for a react component.
I had the same issue and solved it by adding this tag to the parent div that wraps my Vue component.
https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/ui/widget-internals.html#exclude-dom-events-from-default-handlers
Adding from CKE Docs:
Sometimes it can be useful to prevent processing of events by default handlers, for example using React component inside an UIElement in the widget where, by default, widget itself wants to control everything. To make it possible the only thing to do is to add a data-cke-ignore-events attribute to an element or to its ancestor and then all events triggered by any of children from that element will be ignored in default handlers.
Let’s see it in an short example:
<div data-cke-ignore-events="true">
<button>Click!</button>
</div>
In the above template events dispatched from the button, which is placed inside containing data-cke-ignore-events attribute, will be ignored by default event handlers.
I faced the similar issue.
CKEditor will takes all the events on React component which you hosted on Widget.
The work around is to stop propagation of events to CKEditor which are fired from your DOM element(domElement) where your React component hosted.
Here is the sample code:
https://github.com/ckeditor/ckeditor5-core/compare/proto/input-widget#diff-44ca1561ce575490eac0d660407d5144R239
You should stop all required events. Also you can't paste any content inside the input field of React component. That will also listened by clipboardInput event of CKEditor.

Marionette View - unable to reuse template

I have a module called GridView in which i extend Marionette.ItemView like given below:
GridView.View = Marionette.ItemView.extend({
template: "#grid-view-template",
showGrid: function(gridName) {
....
},
....
}
Whenever a grid is to be displayed the caller extends GridView and invokes the showGrid method with a parameter (as given below)
//Module A code
var View = GridView.View.extend({
});
....
someregion.view.showGrid("GridA");
//Module B code
var View = GridView.View.extend({
});
....
someOtherregion.view.showGrid("GridB");
The problem is that when i show Grid A first and then click (on some menu) to show Grid B, i get a blank screen. If i come back to Grid A it shows the grid. If i show Grid B first, it shows the Grid but get a blank screen when Grid A is clicked. (i.e is only shows the grid which is invoked first). I can always go back to the grid that is shown first and is shows :-(
In a moment of frustration i did the following:
a) Removed the template from GridView
b) Added the template to each module
If I do this, it works as expected (code snippet below)
GridView.View = Marionette.ItemView.extend({
//template: "#grid-view-template", (COMMENTED OUT)
showGrid: function(gridName) {
....
},
....
}
//Module A code
var View = GridView.View.extend({
template: "#gridA-template",
});
....
view.showGrid("GridA");
//Module B code
var View = GridView.View.extend({
template: "#gridB-template",
});
....
view.showGrid("GridB");
When each View that extends GridView has its own template all works well - would appreciate it if someone could shed some light on this.
While this works for me, its a pain since each module that needs to show a grid needs to define its own template with a different ID
The template itself is pretty simple
<div id="grid-view-div3"></div>
thanks in advance
-joseph
Having a template in the base class and then extending views off it is definitely possible, as long as your subviews all use the same template. If the templates need to be slightly different ( not sure if you can change this ) then you can keep your base class, have and then in each subview, specify which template to use, like you are doing.
If there is a way to you to make a more general template and have all grids ( A, B, or C, ) use the same div ( from your template), then your first solution should work... it sounds like, while your putting the grid into the correct div that your template provides for module A with showGrid: function(gridName), that using the same function for modular B is looking for a different div
What exactly does showGrid: do?

how to edit dynamically created dom with Aloha editor?

How can I get Aloha Editor to recognize and edit the dynamically created dom/content?
I usually use jquery and use '.live' or '.on' to get this to work but not sure how to using Aloha.
Thanks
To create a dynamic aloha instance:
$(document).ready(function(){
// Add an editable upon clicking on some button Button
$("#Button").click(function () {
var $ = Aloha.jQuery;
$('#somewhere').append('<div class="editable" id="ed" ></div>');
Aloha.jQuery('.editable').mahalo();
Aloha.jQuery('.editable').aloha();
});
Now you can simply get the content:
var e = Aloha.getEditableById('ed');
getContents();
I haven't tested it but it should work.

ExtJS 4 how to create and display a new controller/view from another controller/view?

I have looked over lots of examples of ExtJS 4 MVC, and they all pretty much show the same thing: The application creates a viewport, loads in a view, and has a 'controllers' defined, which init's the controller:
Ext.application({
name: 'AM',
controllers: [
'Users'
],
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
xtype: 'userlist'
}
]
});
}
});
Thats great, but now let's say in my application I want a button contained within my view to open a whole new controller/view, how do you do that?
I think what I am looking for is a way to say something like:
- Create Controller (run it's init code)
- in the controller init code, create the view and display it
Is that correct, and how do you do this?
I want to clarify that in my case I would need TWO individual instances of the SAME controller/view combination. For example, I might have a view with a tab panel and two tabs. I then want to put TWO separate instances of a 'Users' controller and 'user.List' view inside each tab.
I think what I am looking for is a way to say something like: - Create Controller (run it's init code) - in the controller init code, create the view and display it
In extjs, all controllers get instantiated when the application is loaded. You can use the launch method in the Application class to start off a view. And Have a controller listen to events of that view. In a controller, you can always access the other controller using the application object:
this.application.getController('ControllerName1').displayListPanel(options);
In the above code, I am calling a method displayListPanel that is available in ControllerName1 controller. This method holds the code to display a view (a grid panel) onto the screen. Similarly, I can have methods that create views like a new form for data entry. Here is another example:
this.application.getController('ControllerName1').newDateForm();
and In my method:
newDataForm : function() {
var view = Ext.widget('form',{title: 'New Data'});
view.show();
},
Just checked the documentation of new controller and view classes.
It seems to me, that you could always find needed view when you need it.
For example you can:
//somewhere in controller
this.getView('Viewport').create(); // or .show()
check this and view class methods:
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.app.Controller-method-getView

Event Listeners in Backbone View are not being added to objects in the DOM

I've been struggling through my first Backbone app and have started to get the hang of things. I now have a few successful reports that load JSON data from my server (NodeJS), populate a template (Handlebars), and render relatively nicely on the frontend.
The issue I'm running into is that I'm trying to add event handlers to a <select> object coming in from one of my templates and I'm not having much luck.
Here's the template:
// Report - New Clients
script(type='text/x-handlebars-template', id='newClients-template')
// Start Listing
{{#each report}}
.listingName
.youSearched
| Stylist:
.srchResult
select.chzn-select(id='stylists', style='width:350px')
option(value='null') All Stylists
{{#each stylists}}
option(value='{{uid}}') {{name}}
{{/each}}
.clear
And here's the Backbone View:
note: I'm calling the view from within a $ -> so it shouldn't be loading until DocumentReady
# View
class window.NewClientsView extends Backbone.View
events:
'click #stylists': 'selectStylist'
initialize: ->
#el = $('.containerOuter')
_.bindAll this, 'render'
#collection.bind 'reset', #render
# Compile Handlebars template at init (Not sure if we have to do this each time or not)
source = $('#newClients-template').html()
#template = Handlebars.compile source
# Get the latest collections
#collection.fetch()
render: ->
# Render Handlebars template
renderedContent = #template { report: #collection.toJSON() }
$(#el).html renderedContent
return this
selectStylist: (e) ->
console.log 'hit it!'
console.log e
I'm expecting that any time the dropdown is clicked or changed, I'll see the selectStylist function fired. Unfortunately that hasn't happened yet :( I also have inspected the element in Chrome Dev Tools and there are no event listeners set on the object.
I've been stuck on this for a bunch of hours now and have reviewed all the other suggestions for Backbone event listeners (i.e. pass in your this.el as a parameter when instantiating your view), but haven't had any success.
Any help or ideas would be appreciated!
In initialize, you write
#el = $('.containerOuter')
But Backbone.js processes events before initialize—meaning that it's already bound those events to a different #el (which you should see in the DOM as a lonely div).
You can hack this by overriding make, the function that's used to create #el:
make: ->
$('.containerOuter')[0]

Resources