Design Pattern: Using Javascript MVC to build a toolbar - javascript

So I am building a complex web app, part of this involves the building of a tools panel.
The tools panel will be composed of buttons or subpanels.
Each button should have an action attached - it can either be clicked on or dragged somewhere to provide a function
Sometimes when a button is clicked on a panel will appear in the
toolbar with cool stuff in it :)
As the app evolves new buttons will appear
I may want to change the order of the buttons or attach an existing panel to a different button
I want to design this entire app using JQuery MX. The toolbar is the crux of the app and will be coded first and so I aim to use the development of this to learn how to wield my first MVC JQuery app.
Can anyone offer a starting point regarding how to start this kind of beast?
I understand that the controller is the starting point, and is coded as one might a JQuery function but not entirely sure how models and views will work with this in JQuery MX

I actually built a webapp with a toolbar, though not in JavaScript MVC (which I thought was unnecessarily complicated).
Build a config file like buttonName : actionName. The controller runs through the config file and assigns the action to the button's click event.
My toolbar was quite small (ten buttons or so, although they did change), so I kept all the actions in one controller, although each action was only a couple of lines, calling a separate plugin. If you have lots of buttons, you might want to separate out the actions into different controllers.
Then you have a plugin with a set of generic code which handles visual presentation of the toolbar - drop shadows, background-colors, icon management, etc. Just use addClass / removeClass, and style the different button states with CSS. For HTML, I made each button an '' tag, so it degraded gracefully.
Subpanels are just additional functions on the presentation layer.

Related

Ext JS 4.2 primer

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.

Durandal technique to refresh an existing page [view/viewmodel]

I've a dashboard page which shows data relevant to a particular user which is shown in the drop-down at the right hand top corner.
When i select a different user the dashboard should be reloaded/refresh with data relevant to that user.
Router does not work since I navigate to the same page it does not reload the page.Another trick would be to create a dummy page & redirect from there back to dashboard,but i'm looking for a cleaner approach.
My Bad.
Durandal is leveraging KO heavily so i only needed to update the ViewModel & GUI would get autorefreshed. But the dropdown is not a durandal module.So was trying to figure out a way to notify the Durandal module with the change event.
I realized i was also using http://www.jstorage.info/ & it had a callback for pub/sub as well as listener :) , Issue resolved :)

Can a custom navigation link have an arbitrary ribbon showing?

I'm customizing the Quote entity, aiming to replace the stock Quote Products grid with a customized, Silverlight-powered DataGrid. It basically aims to extend the basic "related records view" functionality (mostly, it adds some calculated fields and inline editing, nothing too fancy).
Of course, the more seamlessly integrated the whole thing ends up to be, the better: I skinned it nicely, basic functionalities are there, but the Ribbon is a big issue, I would like it to show up the Quote Details SubGrid ribbon but obviously the thing has no knowledge about what my custom navigation link is showing.
I know Ribbon Rules but they don't seem to address this need; I'm not aware of any XRM function to accomplish it either. Is it even doable ? If so, how can I accomplish this ?
More about what I already have:
I added a custom link (let's name it My Awesome Grid) to the lefthand Navigation Area, pointing to an HTML Web resource (let's name it new_AwesomeGridPage). This resource merely hosts a Silverlight application (which is yet another web resource, new_AwesomeGrid) containing a DataGrid which lists the Quote Details in a customized, fancier way. The grid is being fed via the OData service and everything works smoothly (it could be pointed out that it doesn't really matter where the data comes from and what it represents, and it would be true of course), except for the Form Ribbon which doesn't "switch" like it does when one clicks a builtin navigation link for a related entity. I am thereby wondering how (if?) one can force the ribbon to show the commands for an arbitrary related entity, when a custom navigation link is used to show an HTML Web Resource ?
Hmm bit of an awkward situation, I'm afraid I don't have a detailed solution to this, just an approach.
As far as I know there is no way to just 'hook up' the standard ribbon to a custom Silverlight grid.
I think what you will have to do is; add enable/visibilty rules to all the existing buttons and then disable/hide them when someone is looking at your grid. What form this rule will take I'm not sure, possibly JavaScript.
Then create new buttons with JavaScript actions that communicate with your Silverlight application, then have your Silverlight application perform whatever logic is required.
For ribbon customisations I would suggest starting with the Ribbon Workbench, its an excellent tool for ribbon editing.

javascript mvc framework design practice for edit-in-place interface

I am programming a CMS that allows creating and editing elements (content blocks) on the site in a WYSIWYG manner. basically, when logged in, you see visually the same website, but hovering and clicking on elements brings up either editors (like Aloha) or additional controls.
For instance:
hovering a paragraph would display a
small menu on its side which allows
selecting between left, center and
right alignment
clicking on a paragraph would make it editable
hovering over an image would display a dot on the right side of the image, which can be dragged thus changing the width of the image (height would update proportionally)
hovering any of the blocks in the website would bring up a "+" button that allows to create another block before the hovered block.
etc.
My current strategy is to use a similar technique that i saw used on Nike Better World and have been using ever since: there's an instantiating javascript that invokes jquery plugin on each html element that has a data-controller attribute, the name of the plugin being specified by the data-controller attribute.
Slightly extending this concept i would use it to attach all kinds of controls to the content blocks.
But, being a noob, only recently i came across javascript mvc frameworks like backbone.js. I've been working with MVC on the server side (in Kohana), but never yet in javascript. It seems that i can use it, but it's unclear to me, what would be the strategy. The CMS i'm working on is a kind of a hybrid between a proper javascript application, and an old-school html website. I don't understand, how can i use, e.g., backbone.js's collection object for content blocks, if they are already loaded in the page html (that doesn't make sense to me to load them with javascript).
does anybody have any suggestions?
Quick answer:
ContentModel: It's the data item you want to edit. The actual content. e.g.: $(#mydiv).text();
DisplayView: The view that will display this data (This is where ContentModel is first instantiated and initialized with $('#mydiv).text()
EditView: The view of "editing" this data (a text area perhaps) - When created, initialized with the ContentModel (same model object)
EditTemplate: The corresponding html of "how" the edit box should look like (can populate and create using _.template(...) i.e, a textarea/box etc.,
Now DisplayView holds the current value of the text (in it's model) at initialization itself. If you have an 'edit' button/link on this view (a div block for example), clicking it creates a new EditView and just "hides" the current div (#mydiv) that is showing the text and shows the EditView loaded with the model data in it's place ($.append() is your best friend here).
You click cancel, just hide/remove EditView and show the underlying div back. If you update, on success (from server) just hide the EditView and show the data on DisplayView! DisplayView can subscribe to the "change" event of the model! So once the model changes, the view knows what to do!!
Hope this helps!

Javascript MVC, need help with structure/methods?

I am attempting a single page application. I understand the main concept of how mvc is used to some extent and am using a lightweight framework called backbone.js. My issue however is not with backbone. I actually am having a problem figuring out how to structure my user interface. I have a bar at the top of the page with 4 buttons. Each button opens an instance window within the application. Within Each of these instance windows html, css, javascript will be utilized. Any suggestions on how to structure the core concept of this user interface.
Considerations on my part:
Each window instance has it's own
div with a unique ID (display:
none).
On-load, the application should
already have necessary html, css,
and javascript loaded into dom. The
html should be inside each unique
div pertaining to its instance
window.
Each menu button should modify its divs
display: to block, bringing the
instance window for that button to
front, but hiding all others.
Each instance window has to be
flexible enough to run javascript
within it, so I must be able to
create additional mvc's within each
unique div.
Okay, last comment. Should my user
interface utilize mvc or is
it not neccessary. Also, If it did use mvc
whats the best way to acomplish
this. There many different concepts
with mvc, like creating a view for
each instance window and listening
for clicks. It just gets confusing.
You think any of my considerations will effectively get the job done, and can you offer suggestions?
If I understand correctly, you want to have each button display a popup window, and be able to change the content of each popup window based on some action? I can only speak for how I would use ASP.NET MVC...
I would use jQuery UI Dialog to handle the popup windows, and have a form tag within each popup that uses its own MVC controller using ajax (I prefer the jQuery ajax command). Using ajax rather than a standard submit button allows you to send/receive data to/from the server without refreshing the webpage. You'll need the .serialize to convert your form into the correct format for sending. Each controller action can either return a JsonResult (which gives you back a javascript object you can use) or a PartialView (which gives HTML)...
Hope some of that made sense...
EDIT:
To answer your last point, I would have a model, view and controller for each window... but I am fairly new to the MVC pattern...
Although Sencha's ExtJS may not be for you, they have a very detailed tutorial of how they've structured the framework for MVC.
I'd recommend taking a look at this for some ideas: http://dev.sencha.com/deploy/ext-4.0-beta3/docs/guide/application_architecture.html
Cheers!

Categories