Dynamically add options to select2 with a POST request - javascript

I am trying to add options dynamically to a multiselect form using Select2. Backend is Ruby on Rails and I have defined a create method for the "genre" model (it's a movie db) in question that takes input as json and adds to the database.
The code below works, but only somewhat :)
when I want to add a new genre "abc" - first of all, the select2 drop-down shows "no results" (and doesn't give the option to add the genre).
However in the BACKEND - the entry is actually created and available for future manipulations. In addition - there isn't just one genre "abc" added, but actually one "a", another one "ab", and a third one "abc".
So two things I need to fix - and I don't know enough JS to know how... :/ ...
how do I ensure that only ONE genre - "abc" is created?
how do I make sure that the genre is shown during creation, and selected properly when I update the form?
Code:
$("#genre-select").select2({
tags: true,
tokenSeparators: [","],
createTag: function (params) {
let term = $.trim(params.term);
$.post("/genres.json", { genre: { name: term } });
},
});

Related

Sequelize run hook once after include

I'm new to Sequelize and try to achieve the following:
Assume I have a very simple database with 3 Models/Tables:
Person, Group and Category.
Person has a Many-To-One relation to Group (1 Person can be in 1 Group, 1 Group holds multiple people) & Group has a Many-To-One relation to Category (1 Group has 1 Category, 1 Category can be applied to multiple Groups).
Because I don't want to save the whole Category in my database, but only a short string, I have a mapper in the backend in my app.
Let's say my Category-Mapper looks like this:
//category.mapper.js
module.exports = Object.freeze({
cat1: "Here is the String that should be sent to and displayed by the FrontEnd",
cat2: ".....",
});
So basically, in my database I save "cat1" as the category and every time I get one or more Categories via Sequelize from the database, I want to go into my mapper, resolve the short string to the long string and send it to the Frontend, so I wrote the following code:
//category.model.js
const categoryMapper = require("../mapper/category.mapper");
Category.afterFind((models) => {
if(!Array.isArray(models)) {
models = [models];
}
models.forEach(model => {
model.name = categoryMapper[model.name];
});
});
This works great when I call Category.findAll()..., but does not trigger when I include the Category as in this example:
Group.findAll({
include: [Category]
})
There is this rather old GitHub Issue referencing this behavior, where someone published some code to make sure the hooks run on include. See here.
I tried implementing the referenced code into my project, but when I do, the hook for Category runs twice in my following code:
Person.findAll({
include: [{
model: Group,
include: [Category]
}]
})
My assumption is, that, with the code from the GitHub-Issue comment, my hook gets triggered every time the relationship is detected and the code runs. Therefore the hook runs once after including Group, because Group has a relationship to Category and a second time when Category is actually included, which breaks my mapping function because the second time it tries to resolve the long string, which doesn't work.
I'm looking for a solution that basically runs my hooks once and only once, namely when the actual include for my model triggers, regardless of on what level the include happens.
Sorry for the lengthy post, but I did not find any solution to my problem online, but don't believe what I am trying to achieve is very exotic or specific to my project only.
If there is a better solution I am not seeing, I'm open to suggestions and new approaches.
Thanx in advance!

How to only show specific columns in ui-grid.js

I have json data (REST response) with many (partly nested) parameters but only want to show specif ones.
How to hide all and enable only specific ones? Currently all parameters are shown as columns.
So I do not want to hide one-by-one by excludeParameters or columnDef visible = false (because the list of parameters can be different based on REST response).
Do you have any idea?
My intension is to change the default visibility to false and only the wanted parameters to true (via columnDef visible). Any solution for that?
Thanks in advance,
Chris
My table options looks like this
$scope.tableOptions= {
data : [],
columnDefs :[
{ field : 'firstName'},
{ field : 'middelName'},
{ field : 'lastName' }
]
}
and I am using the directive as
<div ui-grid="tableOptions"></div>
the data will be populated inside the data field of $scope.tableOptions once the rest api fetches result
Each Json object in my case is having more than 10 fields but the table is only showing three fields which I have defined in columnDefs

Kendo edit template array

I have following kendo example with a custom edit template:
In the example there is a custom edit template, so when you double click on the calendar to make a new event this will show with the custom fields.
There is a custom field for "Contacts" which has an array as data source.
This data source is an array I get from the server (takes 1-2 seconds to get).
The fact that the edit template is prepared with tags makes it not possible to simply create in my success (or done) handler of the ajax call that gets the data.
The only way I see is to have the data ready at page load so that the template picks it up.
I want however to either create the template whenever my data load is done or add my data to it after it is loaded.
To simulate the time the server takes for the data to load I use setTimeout of 1 sec, that way the edit template does not pick up the data.
To recreate:
double click on the calendar to create an event
notice that the contact field is empty (because data is not ready at page load)
Any help appreciated
This has nothing to do with the async delay. Your kontaktdata array is local to the anonymous function you pass to setTimeout, so it simply doesn't exist in the context the template is evaluated in.
Your data has to either be defined on the data model itself or in the global context.
The other problem is that the data structure itself has to exist - either a kendo.data.DataSource or an array, and you need to update it with new data if you want an existing view to be aware of that new data. If you simply replace it, the edit template has no way of picking that up immediately (if you open a new edit dialog, it will also work, of course).
So if you do this, for example, it will work:
var kontaktdata = [];
setTimeout(function(){
kontaktdata.push.apply(kontaktdata, [
{ text: "Demo B Client", value: 1 },
{ text: "Martin", value: 2 },
{ text: "Herbert", value: 3 }]);
}, 4000);

Model in from ng-option not displaying results | Possible dynamic model?

I currently list a set of options for ng-options from a resource that contains JSON.
[
{
id:23,
name:"Other"
},
{
id:24,
name:"Crew"
},
{
id:25,
name:"Announcer"
},
{
id:26,
name:"Producer"
},
{
id:27,
name:"Cameraman"
},
{
id:28,
name:"Monitor"
}
]
This is all added into my scope at $scope.broadcaster = response.data. I then loop through everything in my options by a simple ng-options.
<select ng-model="selectedrole" ng-options="roles as roles.name for roles in broadcaster" ng-init="selectedrole=broadcaster[0]">
</select>
Everything goes good once the page loads up. I can select from my list of names and the ng-init starts on the first selection as anticipated. However I have a few issues that I can't seem to resolve.
1) In my doc I set up {{selectedrole}} and I expected to see the contents of my model on the page reflected by my current selection. Instead I see no output at all. I can't tell if the model is even being updated properly so I'm not sure if I can use it in my formdata.
2) This select is generated on click so users can select a role for more than one person. However since the model is the same, any selection is copied over which ever one is changed. I need to find a way to output the model to check the data, but make that model dynamic so i can get a list of results from all the different selections.
EDIT:
Now this is really crazy. I mocked it up in a plunker and its at least showing the model just fine. Are there some conflictions I should worry about that would stop the model from updating? I literally copy pasted my data and its working in plunker but not my project.
http://plnkr.co/edit/GbdOmdjj1M3OuZKO5cSq?p=preview
EDIT2:
Even more info. As I stated before, the select is created when a user clicks on a function that creates an ng-repeat with user information and a new select option for role. If I place the {{selectedrole}} within that ng-repeat I actually get all the data returned when I user selects it. It seems that since the click creates a push of new data, it will not work outside each item. The issues now is that every instance has its own model so i need to figure out how to gather all this data from each ng-repeat and post it to the form. I'll try to update as I work through the issue.

Need to dynamically build checkboxes in angular from JSON object loaded from ajax

I have a JSON doc in the following format and need to use that to dynamically build check boxes using angular.
var data = {
"Name":[
{
"tagId":4489,"name":"Name","label":"Employee Name"
}
],
"Service":[
{
"tagId":1722,"name":"good service","label":"Good Service"
},
{
"tagId":3707,"name":"bad service","label":"Bad Service"
}
]};
I am just learning Angular js and the project I am working on will need the check boxes in the following format.
Name
[ ] Employee Name
Service
[ ] Good Service
[ ] Bad Service
The JSON is loaded on startup with ajax in my main controller. I am not quite sure how let Angular build this for me using the ng-repeat function.
Any help is appreciated.
Check out my fiddle. I belive my answer is a bit more complete than Khalil's.
http://jsfiddle.net/nicolasmoise/8YQPh/1
I have created a factory .factory('checkBoxFactory', function(){}) which takes the JSON object and adds a check="false" to every tag. This may not be necessary, but I believe it's better to set the values right away in case the user doesn't touch them.
Finally, I have directive .directive('checkboxes', function(){}) which takes the checkboxes I have created through the factory and creates the desired markup. With this you can change the name of your categories (Name, Service) and it still works.
Let me know if this is not what you had in mind or if you have questions.
I made a jsfiddle of the most basic example of what you're looking for over here.
Basically I just attached data to the scope and iterated over both lists, "Service" and "Name" and used inputs with type=checkbox(angular docs) and attached an ng-model linked to a check value on each object (this will be added by angular when you activate the checkbox).
You can monitor the values of the checkboxes by referencing check on each object. I do this by doing ng-repeat="service in data.Service" and then calling service.check.

Categories