I am trying to create a car make/model form using Javascript or AJAX, problem is that I don't have a lot of experience with either, but here it goes. . .
I need to create a form that has a car make and model drop down list in it, and when a user chooses a specific make, the model drop down will be populated with all of the models for that make, now I have a few ideas on how to accomplish that, but I would like some input on what the best way would be to approach this, to cut down on dev time.
I was thinking of creating an array within an array, one with the makes, and within each "make" array have the models array in there, so when the user clicks on a make, a AJAX/Javascript function will fire which will take the value of the current field and use that to get the location of the make in the array, which will then traverse through the inner models array and generate the drop down menu for that specific make.
Now I am not sure if this is a sound idea, or if there is a better way of doing it, but I have very little time to test, so process of elimination is out of the question, so could someone please point me in the general direction I need to go in, or maybe point me to a ready made script? as my understanding of Javascript syntax is little to none at the moment!
Thanx in advance!
The key decision is whether you want to load all of the information at the beginning (in which case the user may experience a delay while you load all of the models for the makes that they don't care about) or whether you want to retrieve the models as they choose a make. The answer will depend on
how much data there's likely to be
how fast you need the page to be
how much load will be on the server
etc.
Basically, can you afford the performance impact of loading all of the models at the beginning?
If you decide that you can afford to load everything at the beginning, I think the approach you describe is reasonable, although I wouldn't actually use an array for the outer container. I'd do this:
var models = {
Audi: ["Quattro","A4", ...],
BMW: ["M3", "M6", ...],
...
};
The thing stored in the "models" variable is actually a javascript object, although people do sometimes call it an "associative array".
Note that in this scenario you aren't really doing "AJAX", as you aren't retrieving data from the server on-the-fly.
The alternative scenario is that you set up a URL where you can query it with a model, and it will respond with a list of makes. Then you fire off the query when the user selects a model. That's AJAX.
Related
I'm working on a vue app that uses vuex and gets objects from an api. The tables have paging and fetch batches of objects from the api, sometimes including related entities as nested objects. The UI allows some editing via inputs in a table, and adds via modals.
When the user wants to save all changes, I have a problem: how do I know what to patch via the api?
Idea 1: capture every change on every input and mark the object being edited as dirty
Idea 2: make a deep copy of the data after the fetch, and do a deep comparison to find out what's dirty
Idea 3: this is my question: please tell me that idea 3 exists and it's better than 1 or 2!
If the answer isn't idea 3, I'm really hoping it's not idea 1. There are so many inputs to attach change handlers to, and if the user edits something, then re-edits back to its original value, I'll have marked something dirty that really isn't.
The deep copy / deep compare at least isolates the problem to two places in code, but my sense is that there must be a better way. If this is the answer (also hoping not), do I build the deep copy / deep compare myself, or is there a package for it?
It looks like you have the final state on the UI and want to persist it on the server. Instead of sending over the delta - I would just send over the full final state and overwrite whatever there was on server side
So if you have user settings - instead of sending what settings were toggled - just send over the "this is what the new set of settings is"
Heavy stuff needs to be done on the server rather than the client most of the time. So I'll follow the answer given by Asad. You're not supposed to make huge objects diffs, it's 2022 so we need to think about performance.
Of course, it also depends of your app, what this is all about. Maybe your API guy is opposed to it for a specific reason (not only related to performance). Setup a meeting with your team/PO and check what is feasible.
You can always make something on your side too, looping on all inputs should be feasible without manually doing that yourself.
TLDR: this needs to be a discussion in your company with your very specific constrains/limitations. All "reasonable solutions" are already listed and you will probably not be able to go further because those kind of "opinion based" questions are not allowed anyway on SO.
I created an App for projects and To Do lists. It consists of one HTML page, which only has an "add To Do list"-button.
The user can click on that button and create a To Do list, in this list he can create tasks.
The lists and tasks are dynamically generated HTML Elements.
Is there a way to just store everything, the dynamically generated DOM and all its elements and their functions? I searched for an answer for hours and all I found was a method to store data locally with localStorage: http://docs.phonegap.com/en/1.2.0/phonegap_storage_storage.md.html#localStorage
Since my elements contain a lot of js functions, it would be very complicated to store everything with this method...
Is there no way of storing "the whole thing"?
Thanks in advance!
Your question require a very large explanation, anyway I would tell you some tips you can use to step forward since I worked on a similar app last year.
Think about a database structure for your app. I got a table "Tasks" in which I stored both tasks and subtasks (task inside other tasks). I also stored alarms (if a task need an alarm), texts, checked/unchecked, archived flag, deleted flag, and so on. Everything you can associate to a task, you need a column for it.
Think about your data amount globally. If you plan to store a large amount of data (more or less 5MB) you better choose SQLite approach. If you think your data will not reach this edge, think about LocalStorage. You can google both to manage their use.
When the user fill the DOM to create a task and click on "create" (or something similar), you have to "scan" the DOM, acquire all info for the task created and put them into your DB
When the user want to update/modify a task, you have to find it in the DB, fetch related data, create the DOM's structures you need to show data, fill the structures with data
These are more or less few tips I can give you on your long way. Good luck
Here's a common situation: you have a form and you're interested in the submissions of that form. You may add a wrinkle to the situation by adding a server-side validator, or even a client-side validator, but the validators are only provided as a means of ensuring the input you submit is valid at that instance; any state collected between 0 and submission is thrown away and incidental.
Here's a less-common situation: your form has a password/confirm field that you need to wire to work in the obvious manner and wire to display an indication of password strength (and validity). In the past I've seen a lot of "write a jQuery callback for the event handler on change, and call it a day." This is just a more extreme case of needing the state in between to get to a destination, not as an end in itself.
Now a very uncommon situation: you need to track the input of this form because it is a form used by the US government to communicate with our guys in nuclear bunkers in Wyoming. It is certainly important that form input is valid on submission, but we need to additionally know as much as we can about the way it got there. Let's say it is a login form for instance. If we track the sequence of events from 0 to submission and compare it to the past we can detect anomalies in user behavior, for instance. We can determine whether we might be having login servers problems before we hear about them. So this is not always throwaway info.
I want to map the event onChange to some Diode concept, but I'm having trouble figuring out what I ought to do. Here are the options:
I could define a new case class for each field-type and for each object-type permuted, and stick all of them in the root model (seems like a stupid way to do it)
I could define a genericized data structure representing an "un-submitted change in input value" that would also indicate the model and field changing. Seems optimal but maybe unnecessary and a lot of work and hard to do well.
I could use an existing data structure, like one of the Pots, to stand in place for my Scratch data structure. Probably the best idea but not sure which to use.
That's where I am at... any thoughtful advice is appreciated.
This may be something where using a chat would work better, but here are some thoughts on the matter.
There are three places you could store such an event log:
In the state of the view component. Just add the timestamped events to a list stored in the view state. On submission, send this list alongside with the rest of the data.
In the Diode model. Again, store a list of events in the model and submit with the form data.
In the server. Send each event separately to the server and let it worry about what they mean. No need to store on client side at all.
For such transient data, I wouldn't route it through Diode at all, but instead use options 1 or 3 to transmit it.
I have a rather complex web page with various tabs, forms, radio buttons, drop downs, etc. It's all bound using Knockout.js to a very complex JavaScript object that was loaded via an AJAX call. Of course the user can muck with stuff to their heart's content, at which point they hit a Save button to persist all their changes back to the server.
I'm in the process of coming up with a good design to track exactly what was changed on the page so I can implement saving. So, I've come up with a few possible implementations.
Option 1) Just send everything back and let the server sort it out: With this method, I'd let Knockout just update the data source. The Save button would call .toJS() and send that data back to the server. Pros: It's super easy, and takes very little work on the client. Cons: The server doesn't really know what changed and has to either load the data from the database to compare, or just save all the fields again. These fields come from multiple tables and have complex relations. It also treats the entire document as a single atomic unit. If someone else changed Field A and you changed field B, one user is going to lose their change.
Option 2) Use JavaScript to compare the original data and the current data: Using this technique, when the user clicks on the Save button, I would systematically compare the original data and current data and generate a graph of changes. Pros: This would ideally result in a compact graph of exactly what the user changed, and could even no-op if nothing was changed. Cons: The data I'm binding to is complex. It consists of strings, arrays, objects, arrays of objects, arrays of objects with other objects, etc. Looking for changes would be a rather complex nested loop.
Option 3) Track changes as they are being made in the UI: I would have to observe changes as they happen, and keep a delta as UI elements were changed. The Save button would simply send that change graph to the server if it had any pending changes. Pros: No need to compare two huge JavaScript objects looking for changes, but still has all the benefits of option 2. Cons: Knockout doesn't appear to have a standard way to listen to all changes using a single event handler. I believe I would have to resort to binding to all the UI elements, or creating custom bindingHandlers in Knockout to implement this real-time change tracking.
My Question:
My question is mostly for Knockout.js experts. Is there a standard approach, or recommended guidelines to solving this obviously common scenario? Is sending back all the data, even stuff that hasn't changed, a common design? Or are people implementing custom change trackers? Does Knockout provide any sort of framework that eases this requirement?
Update: Found this thing, not sure if it could be useful or if anyone has any feedback on it.
If it's a question of enabling/disabling the Save button, allowing the user to navigate "from" that page/state, then you can check with the https://github.com/CodeSeven/kolite
check the knockout.dirtyFlag.js
Hope this helps.
Edit: remember that you should "never" trust the data coming from the "UI". The real comparison and validation, ultimately goes in your "controlled" environment within the server.
What I would probably do is take option 2 - the comparison itself can be as simple as stringifying the JS object and comparing it with a cached version of itself.
A few other options are discussed here.
P.S. Maybe ko.mapping can help you manage this monster of a JS object?
I wrote a change tracker extension for knockout that Pete Smith greatly expanded on...
Take a look here:
https://roysvork.wordpress.com/2014/01/12/tracking-changes-to-complex-viewmodels-with-knockout-js/
It works on the principle of extending the observable to track initial state vs. changes the user has made on the client. I think this works really great and can give users real-time feedback to know what they've modified. In practice, we actually implement a save panel that shows all pending changes and even lets them undo individual changes, all by using the change tracker's reusable capability.
ko.extenders.trackChange = function (target, track) {
if (track) {
target.isDirty = ko.observable(false);
target.originalValue = target();
target.subscribe(function (newValue) {
// use != not !== so numbers will equate naturally
target.isDirty(newValue != target.originalValue);
});
}
return target;
};
I often use data-attributes to store configuration that I can't semantically markup so that the JS will behave in a certain way for those elements. Now this is fine for pages where the server renders them (dutifully filling out the data-attributes).
However, I've seen examples where the javascript writes data-attributes to save bits of data it may need later. For example, posting some data to the server. If it fails to send then storing the data in a data-attribute and providing a retry button. When the retry button is clicked it finds the appropriate data-attribute and tries again.
To me this feels dirty and expensive as I have to delve into the DOM to then dig this bit of data out, but it's also very easy for me to do.
I can see 2 alternative approaches:
One would be to either take advantage of the scoping of an anonymous Javascript function to keep a handle on the original bit of data, although this may not be possible and could perhaps lead to too much "magic".
Two, keep an object lying around that keeps a track of these things. Instead of asking the DOM for the contents of a certain data-attribute I just query my object.
I guess my assumptions are that the DOM should not be used to store arbitrary bits of state, and instead we should use simpler objects that have a single purpose. On top of that I assume that accessing the DOM is more expensive than a simpler, but specific object to keep track of things.
What do other people think with regards to, performance, clarity and ease of execution?
Your assumptions are very good! Although it's allowed and perfectly valid, it's not a good practice to store data in the DOM. Sure, it's fine if you only have one input field, but, but as the application grows, you end up with a jumbled mess of data everywhere...and as you mentioned, the DOM is SLOW.
The bigger the app, the more essential it is to separate your interests:
DOM Events -> trigger JS functions -> access Data (JS object, JS API, or AJAX API) -> process results (API call or DOM Change)
I'm a big fan of creating an API to access JS data, so you can also trigger new events upon add, delete, get, change.