I am working on a template builder using ractive js and partials. Once the user finishes building the template he can save it. At this point the HTML code gets saved to the database.
The issue appears when he wants to edit it as everything got saved as plain html so we don't have any mustaches so we cannot bind it anymore.
If I know which template was applied initially, can we bind the template to a specific ractive so we can update the mustaches?
An example could be the background-color of a certain div element
Update: 26-06: Some more details on the workflow: the user drag and drops elements similar to mailchimp. I have some variables that are replaced - like the name, phone number, listing details etc.
I save the generated html in the database, but I think it would be better to serialize all replaced data and when they want to edit what they built, I load each partial and apply the saved data to each template.
Thank you
Related
I have a scenario where I want to show some HTML templates, User can select a template and can do just below things with that template:
Change background colors of those loaded static html divs
Select and change existing images of HTML template (I dont want to add new images on the page, I just want to modify the existing images of that template)
NOTE: All html files are independent static pages which can be used by a user later on. (eg: lets say as a mail template)
Can anyone guide me to its implementation process? I am using angularJS here.
I tried to google but I think I am not getting the exact results, may be I am not choosing exact keywords to for. Thanks !
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 have a chat room style application and each entry is processed on the client once it is received and then some html is generated to display it. As certain messages will have tooltips and other bits of data embedded within them which use knockout bindings to display.
Now after looking over all the posts around this the answers to this problem seem to be:
Make sure all your elements exist up front but are empty
Call ko.applyBindings on the new elements when they are added
The first one is not feasible as you only create the elements as the chat comes in from the server, so the second option seems the only way to do it, however this would require calling for each chat message that comes in. A lot of people say that ko.applyBindings can incur significant overheads, however I think they mean if you were to call it upon all elements rather than just targeting specific ones.
Just so that everyone is on the same page, here is the basic snippet of the view around the area that matters:
<!-- ko foreach: {data: ChatRoom.Entries, afterRender: ChatEntryRendered } -->
<div class="entry-content" data-bind="html: ProcessedContent"></div>
<!-- /ko -->
Ignoring the bits around that, it will basically loop around each entry, add a div which will contain html which will contain bindings which need knockout goodness applied. So for example the ProcessedContent could look something like:
<span>Some content with a <span data-bind="tooltip: 'Some Content Here'">DYNAMIC</span> bit of <span class="special-text">Content</span></span>
So this above html would not currently be processed by the foreach as it is dynamically applied to the page, and before everyone starts freaking out about injecting html into the views, the server does not send down any markup, it just sends down a string with a load of tokens which the client converts into html. Also without muddying the waters too much, in this scenario the ChatRoom.Entries object is culled every now and again so it will fluctuate from 0-200 (usually 100-200) entries at any given time and the rest of the chat entries are cached in local storage, just so there are never more than about 150 bound Entries to the view at any given time.
Here is a jsfiddle showing the issue in a practical example.
http://jsfiddle.net/Mps4Q/8/
The main reason that the html binding doesn't bind the inserted html is because it can be unsafe. But if you know it's safe, you can use a custom binding that does bind the contents. Here's an example from another SO question: https://stackoverflow.com/a/17756777/1287183
Fiddle: http://jsfiddle.net/Mps4Q/9/
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.