Backbone (Marionette) Edit View - backbone.js

How can I implement an editable view? For example, I have a PersonView. The default view will be showing the person info. Then when I double click, I want to enter "edit mode" where I can edit fields. I suppose you can imagine what I mean? Its common "pattern". How can I implement it? The "simple" way might be on dblClick I replace existing HTML with something else. But it doesnt seem right ... How can this be done?

you can achieve this in many ways:
swapping views,
inline editing,
swapping templates
here is a nice tutorial explaining what you need:
http://net.tutsplus.com/tutorials/javascript-ajax/build-a-contacts-manager-using-backbone-js-part-4/

You can add to your text fields some class, for example .disabled. Also you have to disable this fields by adding disabled attribute. Then add css rules to the .disabled class to make it like plain text (remove paddings, margins, borders etc.). Then on dblClick event just remove class and attribute.

Couldn't you just create another view for edit? since you're going to need different events separate inside of the edit view. Here is something I put together in jsfiddle
You can essentially create a new view passing the model that gets updated to the new view and show it in a region
newValue = ev.target.value;
this.model.set('contentPlacement', newValue)
mainView = new MainView({ model: this.model });
App.mainRegion.show(mainView)
http://jsfiddle.net/cLPfw/

Related

Extjs add grid panel to accordion content

I'm actually not sure if this is possible, but I will ask it anyway. I have a group of accordion controls, and within the content body of each I need to display a grid panel. The grid panel needs to have a click event attached to it. I have tried simply creating the grid panel and setting the html property of the accordion to it, but this produces no content.
Is there somehow I can achieve the above?
You cannot have html content (inserted by the property) along with any other content. If you add any item the html property value will not set/overriden. But for sure you can place anything you want into one accordion panel. Even a grid. But for that case, and based on the last question, I would recommend you to reference the view into the grid. You may do this simply by using a ComponentQuery
The click events can be applied by using the control function of the controller.
For your basic understanding:
In ExtJS you seldom use plain html code. In most scenarios you use any sort of component. All is nested within the items-array or dockedItem-array. Items within these arrays get also processed by the layout system.
Some Query examples applicable to the control function
In the following this refers to the controller itself.
You know the Id of the grid (normally you didn't do this). Id's are marke by a starting #
control({'#yourId': {itemclick: this.onItemclick }});
You know the xtype and that there is only one instance of this type. You can also describe a path by using spaces between the xtypes.
control({'grid': {itemclick: this.onItemclick }});
You have set a custom property to grid (you can refer any property this way). This one is fully compatible the the one above. I recommend this one in your case
control({'grid[customIdent=accordionGrid]': {itemclick: this.onItemclick }});
This are just some ways to use ComponentQueries, there are more. For a more detailed explanation you should refer the sencha API for ComponentQuery
Also note that every component implements the up() and down() methods which also support ComponentQueries.
I forgot to mention: For a control the query strictly need to return just one result (only the first one will be taken) a ComponentQuery on the other hand can return multiple results.
This is perfectly possible but the accordion's body is not the place to put that in. You'll need to add it to the items: [] array of the accodion. The body (or html) only accepts html.
Example:
http://docs.sencha.com/ext-js/4-1/#!/example/layout/accordion.html
this one has a grid within it.

How to make an extjs grid a form field?

I have a requirement to create a custom form field that is basically an extjs grid. The user should be able to click a result in the grid. This clicked result should then become the fields value. Also, this field needs to extend Ext.form.field. Here's what I got:
Ext.define('MyApp.field.Grid', {
alias: 'widget.GriedField',
extend: 'Ext.form.field.Base',
I'm a lot of confused on how to add a grid to form field base. Looks like form field base's template expects HTML. How do I get it accept a component?
If you just need to select a value from a list of items. Why not use a combobox?
If you need to select multiple items. There is an example of how to use the MultiSelect ux component in the documentation examples.
http://docs.sencha.com/ext-js/4-1/#!/example/multiselect/multiselect-demo.html
If you really must use a grid. Then I wouldn't bother with trying to create a field type and cause yourself grief.
Add a listener to your grids selectionchange event and update a hidden field in your form with the value you want from the grid. Job done.
I ended up putting the grid on a form indirectly through creation of dependencies on my model.
My model has master-detail, which the detail is just a store reference. I found that using associations did not work for me.
So, in adding a field to a form, I have something that manages changed events for the model (master record) and the detail stores.

How to access toolbar object of nestedlist view from another view's callback in sencha touch?

I am new in Sencha Touch, so I don't know it's full structure. So the question is a little stupid, i guess :)
I have a view it is a nestedlist object. I have created a toolar object inside my nestedlist. Now I want to manipulate this toolbar from another view's callback. How can I access my toolbar object located in nestedlist view from event callback from another view object?
With that little information on your structure (are you using the MVC pattern? No example code given) I can only say that you can definitely achieve this with Ext.ComponentQuery
Lets say you added a custom property to your toolbar named ident='myToolbar' then you can access this toolbar (precisely said any toolbar with that custom property) by calling
Ext.ComponentQuery.query('[ident=myToolbar]')[0]
The result will be always a array but in this example we accept only one result, that is why I added [0]
For further information refer to the API. Ext.ComponentQuery is mighty if you know how to use it.
First give your toolbar an id, for example myToolbar. Then, in your callback, you can do something like this
var toolbar = Ext.getCmp('myToolbar');
to get your toolbar object. Next you can manipulate the toolbar using the toolbar variable, for example change the title:
toolbar.setTitle('New Title');
More info about getCmp() here.
More info about the toolbar here (Check the toolbar's methods to manipulate it).

Combobox clearing value issue

I've stumbled on an issue with Comboboxes in javafx2.2. This is the scenario:
Users click on the 'editFile' button.
Another pane becomes visible (with the setVisible method).
This pane contains 6 comboboxes.
Three of them have fixed items: cboReport, cboSales, cboSend. Three of them get their data from a db (ObservableList) and get populated when the pane becomes visible: cboFile, cboCustomer, cboVet
The user selects a file number from the cboFile. The rest of the comboboxes are beeing set with the correct values.
The user presses the save button, the file gets saved as intended.
Next the user presses a close button.
When the window closes, the data on the pane gets resetted through a resetGUI_editFilePane() method. There is have lines like:
...
cboReport.getSelectionModel().clearSelection();
cboSales.getSelectionModel().clearSelection();
cboSend.getSelectionModel().clearSelection();
cboFile.getSelectionModel().clearSelection();
cboCustomer.getSelectionModel().clearSelection();
cboVet.getSelectionModel().clearSelection();
cboFile.getItems().clear();
cboCustomer.getItems().clear();
cboVet.getItems.clear();
...
When the user opens the pane again by pressing the 'editFile' button I notice that only the 'fixed item' comboboxes have cleared their selection, the dynamicly filled comboboxes show the last selected item although the value from the selection itself is null. This looks like a graphics bug to me or am I doing something wrong?
Is there any way around this issue or what is the best method to reset a combobox?
EDIT 2014/08/27:
This is officially not a bug(clearSelection() does not clear value):
https://bugs.openjdk.java.net/browse/JDK-8097244
The official "workaround" is to clear the value of the ComboBox after clearing selection.
cb.getSelectionModel().clearSelection();
// Clear value of ComboBox because clearSelection() does not do it
cb.setValue(null);
It is very simple. You just need to work with the value property of ComboBox. here you go ....
ComboBox c;
c.valueProperty().set(null);
I hope this works for you :-D
I ran into nearly the exact same situation and came across your question while looking for a solution. Fortunately, I came up with a workaround that forces the ComboBoxes to reset. When you reset the data on your pane, instead of doing something like:
cboVet.getSelectionModel().clearSelection();
cboVet.getItems.clear();
do something like this...
parentNode.getChildren().remove(cboVet);
cboVet = new ComboBox(); // do whatever else you need to format your ComboBox
parentNode.add(cboVet);
You'll also need to do a setItems() again on your ComboBox so the new one will be populated. This is not an ideal solution but it seems to be working as I expect the provided clearSelection() method would.
You can retrieve the items and have them all removed:
cboVet.getItems().removeAll(cboVet.getItems());
I've just tested a working solution with the Java JDK 1.7.11:
combobox.setSelectedItem(null);
combobox.setValue(null);
Hope it helps :)
I use reflection with direct manipulation of buttonCell field in ComboBox skin:
#SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> void resetComboBox(ComboBox<T> combo) {
Skin<?> skin = combo.getSkin();
if(skin==null){
return;
}
combo.setValue(null);
Field buttonCellField;
try {
buttonCellField = skin.getClass().getDeclaredField("buttonCell");
buttonCellField.setAccessible(true);
ListCell buttonCell = (ListCell) buttonCellField.get(skin);
if(buttonCell!=null){
StringProperty text = buttonCell.textProperty();
text.set("");
buttonCell.setItem(null);
}
} catch (NoSuchFieldException
| SecurityException
| IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
}
I think it's also possible by providing your own buttonCell implementation through buttonCellFactory property
I had the same problem with a ComboBox. The buttonCell of the ComboBox is not updated correctly when I change the items of the ComboBox. This looks like a graphics bug.
I use direct manipulation of buttonCell field in ComboBox.
combo.getButtonCell().setText("");
combo.getButtonCell().setItem(null);
This is the best solution I've found without recreate the ComboBox.
To clear SelectionModel I found nothing better than creating a new instance of Combobox (previous answers update):
myParentNode.getChildren().remove(myCombobox);
myCombobox = new ComboBox();
myParentNode.add(myCombobox);
But this solution evolves other problems: if you use fxml, this combobox will be placed in the wrong place and with wrong parameters. Some fxml parameters are hardly reproduced directly from your controller class code and this is awful to do it every time you need to clear the combobox.
The solution is using custom components instead of creating instances directly in main controller class code, even if these components are standard. This also helps to free some lines in your main controller class by moving component related event methods and other methods to a separate class file, where you use a reference to your main controller class.
How to create custom components in JavaFX FXML Application can be found in http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm , but note that CustomControlExample class is not needed for every custom component in your application, if it already has an entry point class with start(Satge stage) method.
How to resolve possible errors with reference from custom component controller class to main controller class can be found in JavaFx: how to reference main Controller class instance from CustomComponentController class?
I need to clear selection of the combo box. And this code worked for me:
List<Object> list = new ArrayList<>(comboBox.getItems());
comboBox.getItems().removeAll(list);
comboBox.getItems().addAll(list);

Switching between readonly view and edit view in backbone js

I am looking for pattern in Backbone js to switch between readonly and edit view. If the trigger for the view is external to the view then no problem I can create the appropriate view ( readonly or edit ) and render it, but in my case the trigger for the edit view will be inside the readonly view.
For example lets say I am displaying a Prescription and by default it is in readonly mode and on hovering a edit icon gets displayed. Onclick of this edit icon the readonly view should now be replaced with edit view. What would be a best approach to achieve this. Below are few options I am considering
Have a single PrescriptionView with the edit icon and all the form fields required for the edit mode in it. It will also have the logic to change the view from readonly mode to edit mode based on edit trigger.
Have two views PrescriptionReadView and PrescriptionEditView. The ReadView will have the edit icon and onclick replace the readview with editview.
I am inclined towards #2 but not sure how to implement it in a elegant way. Any thoughts on this will be helpful.
Thanks
Zafer
Your life will be considerably less painful, if you separate your pretty view from your edit view, since they are, for all intents and purposes, two distinct views of the same data, with different event-handling needs and different behavior. So, your instincts that lead you towards #2 are right on the money.
The cleanest implementation I can think of is to make a container view (say, PrescriptionView) that can handle the mode-swapping events. The container will own a reference to the currently active prescription view, and will handle the creation of that view, and the cleanup (remove and unbind) of the inactive view. That keeps all of that logic nice and self-contained.

Resources