How to work with select input with data coming from a simple relational db model - forms

I'm using Angularjs plugged into a API which retrieves data from a mysqlk normal relational db.
Let's say I have this simple data model in my bdd:
table car:
id,
type_id
table type:
id,
label
I have a API which retrieves the data from DB to have the list of cars and the static labels from db:
http://myapi/car/
response :
{[{id:1, type_id:2}, {id:2, type_id:3}]}
http://myapi/carstaticlabel/
response :
{[{id:1, label:convertible}, {id:2, label:limousine}, {id:3, label:pickup}]}
My aim is first to display a list of cars with the type label and then, open a dialog and being able to show a form with preloaded values of the selected car:
rendered list of cars :
1 convertible
2 pickup
rendered form for edited car whose id is 1:
select the type of car:
<select>
<option value="1">convertible</option>
<option value="2" selected="selected">limousine</option>
<option value="3">pickup</option>
</select>
I have tried different approaches but none is elegant
Solution 1
for the list of cars
change my API and make the join directly between car and type to get the list with label:
http://myapi/car/
response :
{[{id:1, type_id:2, type:{[id:2, label:limousine]}}, {id:2, type_id:3, type:{[id:3, label:pickup]}}]}
then I just assign in the form : car.id and car['type']['label']
ISSUE: each car will contain repeated information (label) >> bloated info
for the edit form:
I pass the json of selected car to the form and set default values:
<p>type: <select ng-model="car.type" ng-options="type.label for type in type_list" required></select></p>
MY ISSUE with that:
when I submit the form, I don't get the type_id directly, I get the car.type object instead, so I need to painfully translate it into an id to post into the database.
To convert I have to go into the car.type object and retrieve the object inside and then retrieve its id... very unelegant.
Solution 2
make the "join" inside angular by working with arrays.
ISSUE: very hard to default values in the form later on
I'm lost, what is usually the best practice to achieve that simple task?

You should use select as label for value in array syntax for array data sources. Your example have complex data structure which is array of objects. So you need something like this:
<select ng-model="selectedId"
ng-options="x.id as x.label for x in response">
</select>
I created little example here to demonstrate proposed solution.

Related

Select options obtained via ajax and unmap issue

I don't see any examples linking a form using select elements with options obtained via ajax. I am wanting to initialize a view model property via ajax in order to populate some select lists in my view and data-link the selected id from my model data. I don't need these arrays when doing an .unmap() of compiled view model because I don't want to send the large lists back to the server when updating the model. So, let's say I have data with ProjectID, ProjectDescription, ProjectTypeID, ProjectPriorityID. In my view model, I need to get via ajax a list of ProjectTypes and ProjectPriorities and use them in my view so that I can select the value from a list. I'm not sure how to achieve this without getting the lists as part of the data when doing .unmap() to send it back to the server.
If there is a property for "ProjectTypes" or "ProjectPriorites" in my view model, they always become part of the data when calling .unmap().
Thank you
There are different alternative approaches. One is to have a single model that includes both 'secondary data' - such as all the ProjectTypes - which will not change dynamically, and the 'primary data' which can get updated based on user input. In that case when you get plain JSON data back from the VM hierarchy using unmap() you can 'prune' it and send only the relevant 'primary' parts back the server.
Another approach is to keep the primary and secondary data separate - so the model is just the 'primary' data, and the secondary data is separate - for example, passed in as a helper:
// Instantiate View Models
var appVm = $.views.viewModels.MyModel.map(modelData);
var typesVm = $.views.viewModels.MyTypes.map(typeData);
$.templates("#appTemplate").link("#page", appVm, {types: typesVm});
<select data-link="typeId()"><
{^{for ~types.projectTypes()}}
<option value="{{:id()}}">{{:label()}}</option>
{{/for}}
</select>
You can also choose not to compile View Models for the secondary data, if it is basically 'static', and do:
$.templates("#appTemplate").link("#page", appVm, {types: typesData});
<select data-link="typeId()"><
{^{for ~types.projectTypes}}
<option value="{{:id}}">{{:label}}</option>
{{/for}}
</select>
Another approach is to only send back to the server any data values or array that have actually changed, for example by using a CRUD/REST web service approach server updates. In that case you would need to have code that diffs the data, or use observe or observeAll to respond to incremental changes...

Meteor tabular tables - multiple tables showing same data

I'm using multiple tabular-tables in Meteor to display sets of partitioned data on the same page. Each occurrence of the tabular appears in a separate template instance, but they all refer to the same table. I have a template that looks as follows:
<template name="parentTemplate">
....
{{#each folders}}
{{> childTemplate}}
{{/each}}
....
</template>
<template name="childTemplate">
{{> tabular table=Table class="..." selector=selector}}
</template>
folders returns a set of partitions for the data, selector just returns {folderId: _id}
My Tabular.Table constructor is pretty simple, the only thing of note is:
changeSelector(selector, userId){
const ret = _.extend(selector, {status: "active"});
console.log(JSON.stringify(ret));
return ret;
}
the console.log part returns what I would expect, for each table a different folderId. When I put the logged selector into mongodb, I get the expected partition for each table, however each table shows me the same set of data as the first table. Additionally, when I click "next page" all the tables update to show the partition that should be displayed in the final table. I've checked that all the tabular table elements in the HTML have unique Id's.
Am I just using tabular-tables incorrectly?
EDIT:
After some tinkering, I found a potential solution, but it isn't clean, so I'd still like to hear people's thoughts. What I did was declare a meteor method as follows:
Meteor.methods({Table: function(){return new BlahTable(...);})
This is executed on the client and server, creating the relevant tabular table in both locations, then I use the newly created table in {{>tabular...}}

Parse Data Model for users tagging items

im trying to figure out a good data model approach when using parse (underlying mongodb) for users that are allowed to select a tag and provide a value to them, lets call it just a rating since thats the easiest to understand.
Im working on a class that is called user tags that has the following structure currently in its collection.
User (pointer to user class)
Object (pointer to object to tag)
Tags (array of tags with values)
The tags can be up to maybe 30 tags and each one of them can have a rating of 1-5 in this case...
I was wondering if I could do a PFRelationship in an array that has the objectId of the tag as the key and value as the 1 - 5 rating.. here is an example json object mocked up to what im saying.
{
"3q24afadfadf": 3.5 //parse relation object id : value,
"234rrdfadfk": 2.4 //parse relation object id : value,
"as4q2w34lsdf": 2.3 //parse relation object id : value
}
This way I can store one row for the item that the user tagged and all the tags with its rating value along with that.
I'm not sure this is the right way or if its scalable when doing queries for get me all users items he or she tagged, along with the tag (name) and the values).
I also on top of that need to figure out a way to when many users tag the same item with different values that I build up some analytics or maybe counter class that gets incremented or averaged in to then be displayed along with the item. I might try cloudcode to do saveafter to update the analytic data class for that item.
Anyhow Any thoughts on this model would be appreciated and most importantly need to be able to get at the data inside the tag array, with hopefully the key being a pointer, if not a pointer i'm up to suggestions because the result should return
Item A
Tag name 1 with value 4.5
Tag Name 2 with value 3.5
and so on..
...
Also if you have any pointers to how to build aggregated data of the item and its over all value that many users have tagged over time.. My thought as above is to have a analytic class that the cloud code increments or that the app then increments, the challenge is to load all the user tags of item x, and get the tag and value out of the array and then add them to the analytic class. I could run this at night since it doesn't have to be real time.

inserting hidden data in form with blade

I am trying to understand how I should treat data in a blade template for a form.
Let's say I have a view to which I send data from an ages_table from the db.
For example I will get these data from 2 columns in the ages_table id, age (1, 40 - 2 ,41 and so on).
Then my form displays a selector where you can chose your age, example 40.
Now.. when I perform the post I need to send the id of that age, in this case 1 and not the number (40) so that I can store it in a user_details table that references the Ages_table example in column age_id of user_details table, in this case 1.
What I am thinking is I need the id in the selector but it needs to be hidden so that when I post the data I only get the id and not the 40.. but maybe that's not how you do it in laravel and eloquent. Any hint?
Why can't you set the option value as the id?
<select name="age">
#foreach($ages as $age)
<option value="{{ $age->id }}">{{ $age->name }}</option>
#endforeach
</select>
So user selects age and server receives the ID of the selection. Is your view not receiving this data?

Getting the value and text from a selectbox in ColdFusion

I have several values in a select box. Is it possible to get both the value and the text between the <option> tags when the form is submitted?
<option value="413">Highland </option>
<option value="414">Inverclyde </option>
Alternatively I suppose I have to store the names in a table or array for retrieval but would be much easier if I could just insert both in the table when the form is submitted.
As Stephen Moretti pointed out, there are at least two ways to derive the text from the value.
You could also use a list containing the value proper and the text for the value of the select. So, instead of:
<option value="23">Twenty Three</option>
use
<option value="23,TwentyThree">Twenty Three</option>
and use list*() functions on the back end.
Finally, you could use JavaScript to store the text of the selected option in a hidden field (or similar). This, in my opinion, is the least attractive option. First, it would be more work than the other options, and second because it will fail if JS is turned off on the client.
Depending on the size/type of data, I would probably either rewrite the option values, as I've described, or switch off a lookup table, as Stephen described.
If you've only got a few value/text pairs in your select, then just store the value. If you need to output the text somewhere else other than the select, just write a if/elseif/else or case block to display the text.
If you've got quite a few value/text pairs then it would be best to create a lookup table in your database with these in. You can use this to generate your select and output the text from a stored value at a later date.
How do you tell if you've got too many value/text pairs? If writing the case block to display them results in a silly amount of tedious code. ;)
Another option would be to store a struct of your value/text pairs in the session scope, then on your form action page you can use the value to easily look up your text.
The beauty of this is that it's entirely server-side and does not include an extra trip to the database.
Delete the struct from the session scope if you don't want to keep it around.