I've written some code for custom entities that dynamically presents questions that the user must answer. The code creates answer records, that are then associated with it's parent record.
My issue is that I'd like users to be able to complete the answers BEFORE having to save the record for which they are answering the questions. The problem is that in order to associate the answers records to a parent record, the parent record must have a guid value, and this is only created once the record is saved.
My idea is that I can store the answer record guid values in a global array, and OnSave of the parent record, go update the answer records accordingly to link them to the parent. BUT when I save the record, my global gets wiped clean.
Is there any way to preserve the values stored in that global array? Or does anyone have a more clever way to route around this issue? Thanks very much for any help.
Keeping in mind that you're using a HTML Web Resource and you will have access to the Global Context, I can think in these alternatives:
Force the user to manually save the record: I know that you want to avoid this option, but this behaviour would be similar to the one that the grids have (they show a message which says "To enable this content, save the record"). You can accomplish this using the Form Type.
Save the temporary data in a hidden field: instead of using a global array to save the answers you can use a hidden field in your parent entity so the data will be preserved. You will be able to create the related entities when the form loads again (to reuse the code that you have in place now) or use a plugin (Post Create of your parent entity).
Related
I have a website built with Vue.js and I need to do an audit and, optionally, implement cancel functionality for this website so I'm looking for my options/best practices.
Let's say I have an Items array defined in data() so on created () I'm doing an Ajax request and pushing data into this array of items.
Now user loads this page and does his job which for me means he changed a few objects. Let's say each Item is a Customer object and it has First name, Last name, DOB and a IsActive boolean field.
I would like to give this user an option to revert specific item to the original state without reloading anything and when he hits Save I would like to know what was changed (so I can log this information)
Here are my ideas so far:
keep a copy of the original list of Items and do a diff later to see what was changed or use it to restore objects as needed
try to utilize watch() and keep track of changes. Perhaps, I can even store this information in the object itself.
leave a UI as is and on the backend (while saving or updating) re-read object from the DB and do the job there since it is the only truly secure way of doing an audit anyway.
What's the best way to track changes and/or implement both cancel and audit?
Maybe there is a Vue-way of doing this which I'm missing, because I just switched to Vue from a different framework.
Thank you! Any help appreciated!
I have an array of Device objects which is fetched regularly from a REST server using $resource. Whenever this happens, the UI gets "reloaded", meaning the ng-repeat for this device array is executed again. The DOM update is annoying, because it screws up the current user interaction with devices. Instead I want the newly fetched Device array to update the existing one only WHERE stuff has changed. So if I get a fresh Device array, and there was only a name change in one of the 10 devices, then only that single data binding for that name of this one device shall incur a DOM update.
I couldn't find a method of doing this. Since it seems a common problem to me, I wanted to ask before writing my own "mergeUpdate" method which basically just does a deep-compare-replace operation and only write the things into the existing binding that actually have changed on the server-side.
Note that each device is uniquely identified by an id, thus this algorithm is possible at all. Without this id field it would not work (probably the reason why there is no generic method supplied with AngularJS).
Actually, angular.equals is a partial solution. Now I want something that can at least transfer modified properties too, without invalidating the whole array.
Thanks!
What you are looking for is "track by" for ngrepeat. In your case,
<div ng-repeat="item in items track by item.id"></div>
With this, ngrepeat will keep track of existing items and not rerender them. The merge logic is internal to ngrepeat.
Let's say I'm on a screen editing a post (and its associated meta-data). Now, the post has many categories, tags, and possibly other related items (hasMany).
When saving the entire post, I have to save the post and every single entity associated with it. This is how I do it in AngularJS:
All the data is stored in a separate model so that it can be universally accessed. Each related entity has multiple meta-data indicating whether they're new, dirty, or whether they have server-side validation errors.
A different controller called "SaveCtrl" manages saving. It goes through all the entities of a post, figures out the ones that have changed, and only sends them along with the post to a single save endpoint.
I have a factory that parses the response from the server. An element might not get saved due to a server-side validation error. Regardless, once we get the response, each of those entities have to be updated with the new state and validation errors. This allows the server-side to update entities without any errors, while returning errors for the few that did have validation errors.
Now, here are some problems with this approach:
The saving is not entirely RESTful. While retrieving data, I believe I should probably make multiple GET calls for each resource (URL design for an API). However, I don't know of a similar approach for saving. Should I save a collection, or a single entity at a time?
The meta-data for each entity (specifying whether it's new, dirty, saved, or unsaved) has to be put in the model data itself. Since ng-repeat creates a separate scope, I'd ideally like to save such state information in these separate scopes, with the ng-repeat elements wrapped in a controller that'd handle this.
My question
Which strategy should I use to save an entire post with all its related entities? Or is my present strategy good enough? Let me know if there are some additional details required.
I'm building a web app that displays a list of customers in a table. There are roughly 15 columns on the table containing different bits of data on these customers. The cells on the table receive user input frequently to update their values.
On page load, the web app sends off an AJAX request with qualifiers to retrieve the appropriate subset of customers out of all active customers. JSON is returned and extended on a global array of objects. Each item in this global array of objects represents a row on the table: var myCustomerList = [{customer_data_object_1},{customer_data_object_2},{customer_data_object_3}].
The HTML for the page is then generated via JavaScript, jQuery, and mustache.js templates. The JavaScript will loop through the global data object (i.e., myCustomerList[i]) and generate rows. I use jQuery's .data() method to link the row itself back to myCustomerList[i]:
$('#tbl_customer_list tr:last').data('cust_data',myCustomerList[i]);
I bind events to UI controls as each cell is appended to a row using jQuery:
$('#tbl_customer_list tr:last td:last a').on('click',function(event) {
custList.cellEvent.status.openDialog(this,event);
});
Event handling functions then refer back to my global data object using jQuery .data():
custList.cellEvent.status.openDialog = function(oLink,event) {
var oCustData = $(oLink).closest('tr').data('cust_data');
//update the global data object
oCustData.status = oLink.value;
}
I have separate code for reconciling changes made to the global data object with the data on the DB tables.
If the above confused you, this page gives a good overview of the client-side MVC approach I'm trying to take: https://sites.google.com/site/jollytoad/mvcusingjquery
So, two questions:
What is a better way of linking model data (browser-side) to the various UI components on the page? Remember I'm using .data() to create a link between the table row DOM element and the global data object.
What is a better way of organizing/storing the model data (i.e., myCustomerList)?
What I'm doing now works, but it seems a little hacky and I'm polluting the global namespace. I don't know how supportable and maintainable it'll be if we ever have to come back to this page and add widgets independent of the customer list.
I've been considering creating a class for the customer list table as a whole (and a new class for any other new widget added to the page) and storing the model data on a property of that class. But I thought I'd come here first to get some tips on best practices in this area.
Use a framework designed to handle this sort of thing, like Backbone, Spine, JavaScriptMVC and so forth.
We use Backbone where I work to handle all of this stuff -- it integrates super well with jQuery.
i think you should take a look at this instead:
http://addyosmani.com/largescalejavascript/
it's a modular pattern to handle various parts of the website. this pattern makes parts of the website independent of one another. each module can have it's own MVC and store it's own states. modules do not have the full logic of the application. it's handled by a sandbox API and core API.
as far as i understand, you load the table's data from the server into the table using AJAX. what i suggest you to do is make that table an independent module.
when it receives the AJAX data, store it in the object
after that, render your table based on that object, store the data into the table. what you put in the table is just the visual data. the actual data remains in that object earlier.
whenever you click on an item, the data in it is an exact reference to the original object you put in. whatever you do to it affects the original object.
Boris Moore is currently working on JsViews & JsRender which is the 'official' jQueryUI way of doing data binding and rendering. It‘s already usable and going beta soon.
I am in a situation to write some client side validation. For example, in a page I use a Repeater control which creates a list of item. There we could select number of items using a check box (in the first column). So if I click 'Delete' button, the selected cases will be deleted. So I need to check if the selected item's count is zero or not. So my question is, where should I write this kind of validations ? In a common .js file or in the page itself.
This should be done in a separate file. You will encounter times when you will need to have the id of the control being validated for one reason or another so you should provide a manner within that file to receive those ids (parameter name in a function, global variable (not recommended), custom namespace object).
Definitely in a separate js file. Then you could reuse the logic on another similar page.
Best practice suggests that you should place this in a separate file. Personally, I would always write this kind of validation server-side, not javascript, especially if the resulting action is a delete.
I would use javascript to allow for a "select all" feature and I would use jQuery to create an "Are you sure" prompt.