I have an existing page in Ember.js for flagged content and displays it. I want to have this content be drag-and-droppable. Doing this in a new model is as trivial as adding a sortOrder property and binding the values, but I want this to only apply to the model within this view. Any pointers? Can link to a JSbin if needed
Related
As the title states, I need to filter results of an associated view based on a record's field value and user permissions.
I've used some Javascript to achieve this whenever the iFrame loads, but if the user switches to a different view, my Javascript is not called and the filtered records come back. I've tried to implement an event listener for various changes within the iFrame, but haven't been able to get what I need. I've gotten onclick to call my function whenever the user opens the view dropdown, but I need it to call whenever they actually switch views.
Am I over complicating this and there's a native way to do this? Or does anyone know how to detect changes within an iFrame?
Unfortunately there’s no native config to do it by OOB. I recommend these.
Don’t rely on associated view, as the name suggests it’s for seeing all the associated records. Remove navigation item in Form editor to remove them if you don’t want your users to see it
Use Subgrid for all your different needs, but not with view switcher, as again you will get roadblock of view switch triggers, etc. also this is going to be unsupported approach to rig the FetchXml with your custom filters
Custom HTML with grid is better or even PCF control of your own to take query & filters
Plugin on RetrieveMultiple can be used in worst cases
My company just bought a third party application which is based on the ext js 4.2. framework.
The software is closed source, but it is web based such that I can add a .js file to change the UI to my needs.
I want to add some controls to the rendered page. The software is showing IDs everywhere instead of text.
Example: "Issue created by: ID123". When I hover the field is get "ID123. John Doe". Ok, I am a JS ninja, so I can just add a field to the HTML DOM which will display "John Doe"in the correct spot.
I looked at the HTML code to get the correct control and see the the IDs are generated. The code I would write is prone to break with each new release of the third party software.
Now, since the is an Ext JS application I can probably solve the issue much more elegantly like adding a field not to the DOM directly but to the Ext JS container.
Question:
In Javascript I have a reference to the Ext JS app. How would I access the current view or viewmodel or model to query data and add a field?
Rough idea/Pseudo code:
var id = app.getCurrentModel.getValue("creatorID");
var name = myserver.getPersonData(id).name;
app.currentView.addLabelControl(name);
I googled a lot but all examples I found assumed that you are writing the ext js app and you are already in the controller or the view. But I only got the reference to the app.
Sorry for the newbie question :)
"App Inspector for Sencha"
For a quick glance over component hierarchy, you can use the Sencha browser plugin,
Find a certain ExtJS component programmatically
To quickly search ExtJS components or transform your findings into code, your main tool will be the browser console and the command Ext.ComponentQuery.query(xtype), e.g.
Ext.ComponentQuery.query("grid")
Ext.ComponentQuery.query("panel")
Ext.ComponentQuery.query("form")
You will then find in browser console an array of all components of that type. Select the right one, and check whether it has an id or itemId that is not auto-generated (everything like xtype-1234 is auto-generated). For form fields, the name attribute could be useful. Commands like
Ext.ComponentQuery.query("[itemId=ABC]")
Ext.ComponentQuery.query("[name=DEF]")
Ext.getCmp(id)
are far more readable and not as prone to side effects as Ext.ComponentQuery.query("panel")[12].
Most of the time, it can also be useful to think in tree structure. If you want a certain container which contains the only slider you see, trying
Ext.ComponentQuery.query("slider")
Ext.ComponentQuery.query("slider")[0].up()
could be easier than sifting through dozens or even hundreds of containers. Ways to traverse the component structure include up(xtype), down(xtype), nextSibling(xtype), previousSibling(xtype). If an xtype is provided, the next component of the corresponding xtype is selected; if it isn't provided, the next component is selected regardless of the type (e.g. direct parent, adjacent sibling).
Change anything you want.
You can extend, debug or modify any existing behaviour, including but not limited to ExtJS's own code, using a so-called override over any component, including the views or stores that make up this app. override makes a great search term for further information.
Or you can add new components to existing components, like a button to an existing form, from outside the app. For example, open sencha docs and then insert in console:
Ext.ComponentQuery.query("searchcontainer")[0].up().insert(1,{xtype:'button',text:'Test',handler:function(){Ext.Msg.alert('Test Button clicked');}});
You should then find a button on the top left, right of the Sencha logo. Click it.
Find existing controllers
For this, you have to find the name of the app namespace.
If it is e.g. MyApp, then MyApp.app.controllers.items contains the list of controllers. Controllers contain control logic, and the mapping between the components and the logic. When components are created, controllers attach their events to these new components. Many changes can and should be made in the component layer, because controller overrides are messy.
Find viewmodels
You're already done, ExtJS 4.2 does not support them.
Changing models
If you want to change models, be cautious: There is no supported function to add fields to a model. You can override the model prototype, and push more entries into the fields array. But if you have any model instances (records) already running around by that time, they are not updated and any existing warranty is voided.
That said, you find them in MyApp.model. You can e.g. get all fields of the Sencha Docs' Comment model using Docs.model.Comment.prototype.fields, or even push another field in.
In my marionette application I have one view which holds handlebar template within {{#each}} expression to display collection of information. Now I want to add "Edit functionality to information displayed using this template. I am thinking of defining one more editable template. But I need help on How should I;
1) render editable template on click of some button
2) send displayed data to editable template as source
3) after changes save request complete how to restore display template with updated values without refreshing complete parent view.
Can any one guide me to implement this functionality; or else can suggest me other better alternative approach to do this.
I am building a large HTML form using Backbone. Each form field is an instance of a Backbone model called Field. I have a Backbone collection called Fields that fetches a JSON file and instantiates all the form fields.
Here's my issue: When I render the collection of form fields, I don't simply want a uniform list of form fields. For example, most backbone tutorials online show you how to render collections by wrapping each model's view in an li with the collection element being a ul.
Rather, I have an HTML template that is broken up into sections like so:
I'd like the "month" and "year" fields to be in one div while the other fields go into their respective divs. The fields will be styled differently from one another using CSS. Is it possible to pass a large underscore template to a collection and have it print its model instances into the appropriate places?
Is this a use case for something like Marionette.Region?
Any thoughts are appreciated!
I see 2 main approaches for your problem:
The simpler way: Make your form be one big itemView and pass it a form model with a fields property (which would be your collection). Then, within the view, you need to iterate and generate the html.
The cleaner way: Use a layout for your form, and render additional layouts into the "time", "location", etc. regions (as suggested by Lilith). For example, the "time" layout would contain the "month" and "year" views. The "month" view, in turn, would be a collection view rendering each option in the collection into an option for the select tag.
Although the first solutions tends to be simpler to implement (because it's closer to traditional stateless web development), the second one will be easier to manage. You'll be able to register event handlers on each view (e.g. select tag) without naming collisions, and since the form's complexity will be broken down into individual pieces, it will be easier to manage down the road.
I'm not sure I totally understand you question, but I think you may need more info in your field model. For example you could include a group property in the field model and then render all fields form the same group in its own div.
Is this what you're trying to do?
I would choose another approach:
Break up the one template into at least different templates (Time, Location, VehicleInfo), because, these are three different topics, which I would handle in separate views.
After that breaking up the Time-View into a Month and a Year view and so on.
Accordingly each subview has its own model with values to render its HTML. I see no sense in using a Collection here - since you have heterogenous 'fields' / Models.
After that I would use something like a form backing Model, which represents the current state of the form. So the implementation of a formView as a super view and the other views as nested views would be a good choice.
var FormView = new Backbone.View.extend({
initialize: function(){
//initialize all subviews
},
events:{
"change":"formChanged"
}
formChanged:function(element){
//update formBackingObject aka this.model
}
});
Then you have a clear separation for all of your views and one model to represent the state of the current selections.
I think you can make use of Marionette CollectionView. With collection view, you can specify different view for each item in the collection. See the documentation;
https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.collectionview.md#collectionviews-itemview
If you want control over where items will be rendered, you can override appendHtml to indicate how itemView's will be appended to collectionView
What's a good way to organize views? Let's say I have a div that will contain a view from an admin panel perspective of users - there will be a list of users along with options to choose how many to display at a time, sorting options, what page to be on, filters, etc...
Would I want an outside view that contained everything except the table and data? And then an inside view that contains the table (along with the data)? And would the pagination have it's own view? And how would the pagination view use the click event to update the user view? I'm just confused on how to organize the views while still being able to have different events trigger other views to render() / collections to fetch().
So a basic hierarchy would look like:
- User View
- Table
- List of Users
- Pagination
- List of available numbers to click
- Filters
- Possible filters to apply to the data
Yet clicking a filter or number in the pagination should be able to get the collection to fetch() new data and refresh the view;
I second dogenpunk. I would have one User Collection / View. Because the whole hierarchy you describe above is about that one User Collection. All functions of it manipulate that collection and then you rerender the User View.
You could have a second User View, one single User, tied to a Model if you want to apply changes to the server for that user only.
I try to reflect my server-side MVC structure as much as I can.
Everything that can be put into a plugin, I do so, and then I keep those plugins in a separate location to the controllers which call the plugins. So in your case, the table view for the list of users would be held either in a table plugin, or possibly in the 'users' module if it was code I was really only going to use once.
If I need to override the output of the plugin, then I store the view inside the module folder.
What I try to avoid doing is storing views purely by the type of HTML inside them, so I wouldn't store a module's view as 'table' because that will get confusing if later it changes to a list. Obviously, if I have a 'table' plugin then the view for that is going to be a table, but then changing the JavaScript view means just changing the plugin call from 'table' to 'list' anyway.
My 2 cents to your original question. If you really want to make it a MV*, a pagination would be a view, your table would be a view. And have your collection to send out ( trigger ) events to change your view. And another questions I would ask myself also is what will be affected when my collection changes? For example, in your case, I don't think the collection changes will affect your userView directly, it only affects the Table and Pagination.