I have a rails app that uses cocoon
= link_to_add_association
to call the partial form
on the main form I have the coffee script to load all of the data for the select2 elements
when the ajax partial is inserted the select2 element doesnt appear. I need to instantiate it.
This is my form coffee/js
$(document).ready ->
$(".select2").each (i, e) ->
select = $(e)
options = {}
if select.hasClass("ajax")
options.ajax =
url: select.data("source")
dataType: "json"
data: (term, page) ->
q: term
page: page
per: 10
results: (data, page) ->
results: data
options.placeholder = "Select a value"
options.allowClear= "true"
options.dropdownAutoWidth = "true"
options.initSelection = (element, callback) ->
data = {id: element.val().split('||')[0], text: element.val().split('||')[1]};
callback data
select.select2 options
return
If I use the coocon - insert after binding to
$('body').bind 'cocoon:after-insert', (e, inserted_item) ->
$(".select2").each (i, e) ->
select = $(e)
options = {}
if select.hasClass("ajax")
options.ajax =
url: select.data("source")
dataType: "json"
data: (term, page) ->
q: term
page: page
per: 10
results: (data, page) ->
results: data
options.placeholder = "Select a value"
options.allowClear= "true"
options.dropdownAutoWidth = "true"
options.initSelection = (element, callback) ->
data = {id: element.val().split('||')[0], text: element.val().split('||')[1]};
callback data
select.select2 options
return
I get all elements on the page refreshed - naturally as I call all select2 objects. I didnt write this code for the select2 js.
All of the existing form elements are ok, but those elemeted added dynamically get refreshed - so they loose the values they have.
I want to only select the element added and make it work.
if i try
$('body').bind 'cocoon:after-insert', (e, inserted_item) ->
$(inserted_item).find(".select2").select2
return
It doesnt work either
Tried many options but my hair is thin now and I am needing help. JS is my arch enemy I really find it a pain .....
HELP!
$(document).ready ->
$('body').bind "cocoon:after-insert", (e, inserted_item) ->
select=$(inserted_item).find(".select2.ajax")
options = {}
if select.hasClass("ajax")
options.ajax =
url: select.data("source")
dataType: "json"
data: (term, page) ->
q: term
page: page
per: 10
results: (data, page) ->
results: data
options.placeholder = "Select a value"
options.allowClear= "true"
options.dropdownAutoWidth = "true"
options.initSelection = (element, callback) ->
data = {id: element.val().split('||')[0], text: element.val().split('||')[1]};
callback data
select.select2 options
return
Omg. hours on this and then I get it ....
Related
I have the requirement to send filter values via OData-service, to fill a table with relevant entries.
So basically there are input fields, where you can select e.g. "AA" (american airlines) for Carrier-ID.
So the filter values need to be created dynamically, regarding to the user input.
I tried following:
var aFilters = [
new sap.ui.model.Filter({
path: "Carrid",
operator: sap.ui.model.FilterOperator.EQ,
value1: "{selection>/Carrid}"
})
];
oModel.read("/SFLIGHTSSet",{
method: "GET",
filters: aFilters,
success: function(oData2, oResponse) {
var oJSONModel = new sap.ui.model.json.JSONModel();
oJSONModel.setData({
modelData: oData2.results
});
oTable.setModel(oJSONModel);
oTable.bindRows("/modelData");
},
error: function(oError) {
console.log("Error!");
}
});
But that doesn't work.
I receive in back-end following request:
"( Carrid eq '{selection>/Carrid}' )"
So the binding doesn't work in the filter-creation...
The binding is correct because I can use it the same way in a Label:
new sap.m.Label({
text: "{selection>/Carrid}"
});
I researched a lot and know that people have problems with it in XML views.. but couldn't find any solution for JS-Views.
I guess your problem is in the line
"{selection>/Carrid}"
Get the value of the User-Input from the Control somehow like this
var sCarrid= this.byId("MySelection").getBindingContext("selection").getProperty("Carrid");
and modify your Filter
var oFilters = [ new sap.ui.model.Filter("Carrid",
sap.ui.model.FilterOperator.EQ,
sCarrid) ];
I need to get data from my Ruby on Rails application, for that I made a pretty simple AngularJS controller:
# /app/assets/javascripts/angular/comments.js.coffee
app.controller 'CommentsController', ['$http', ($http) ->
store = this
store.comments = []
$http.get('/photos/3287.json').success (data) ->
store.comments = data
return
]
It works absolutely fine with the hard-coded :id, but I'm stuck with how to make it change dynamically. What is the easiest way to get an :id from Rails?
I suppose, you wanna edit it? So, you shouldn't use AJAX, you should create factory and use Angular $resource, so you fetch it with :id, set it to $scope, and use it in future.
MORE ABOUT Angular $resource - use Angular way
I believe you can include :id in the URL and then pass the id as a parameter to the get.
# /app/assets/javascripts/angular/comments.js.coffee
app.controller 'CommentsController', ['$http', ($http) ->
store = this
store.comments = []
$http.get('/photos/:id.json', {id: photo.id}).success (data) ->
store.comments = data
return
]
EDIT: I may have misunderstood. This is how you pass an id to $http, but if you need to get the id itself use $resource as Oleg had answered.
Thanks everybody. Here is my working code.
# comments.js.coffee
app = angular.module('comments', ['ngResource'])
app.controller 'CommentsController', ['$scope', 'GetComments', ($scope, GetComments) ->
store = this
store.response = []
$scope.init = (photo_id) ->
GetComments.get({id: photo_id}).$promise.then (data) ->
store.response = data.toJSON().comments
return
return
]
app.factory 'GetComments', ['$resource', ($resource) ->
$resource('/photos/:id.json', null)
]
Also I had to add ng-init to my view like this:
# foo.html.haml
%div{'ng-controller' => 'CommentsController', 'ng-init' => "init(#{#photo.id})"}
Does the Select2 jQuery plug-in have a built-in function for converting strings to tokens?
I want to be able to call this tokenizing function when the user pastes strings into a Select2 field so that the pasted input becomes tokens.
I think I have solved the question myself with the following code:
// force tokenizing of Select2 auto-complete fields after pasting
$('body').on('paste', '.select2-input', function() {
// append a delimiter and trigger an update
$(this).val(this.value + ',').trigger('input');
});
This assumes that commas are set as delimiters in the plug-in's "tokenSeparators" initialization setting.
For 4.0.1 version:
$('#my-select').data('select2').dataAdapter.$search.val("tag1,tag2,").trigger("input");
This will add two tags: tag1 and tag2 (note trailing ,).
Important: you should add data: [] into select2 init parameters.
Use an input type text, and assign the select2 to it. Like
<input type="text" id="makeTokens" />
and then in javascript
$("#makeTokens").select2({
placeholder: "Paste data",
tags: ["red", "green", "blue"],
tokenSeparators: [",", " "]
});
in the tags, you can assign any values that you want it to display as select options and use the tokenSeperators to seperate the text on commas or spaces etc.
Note: The resultant input value will be comma seperated tokens.
For some reason Donald's solution didn't work for me (maybe newer versions of select2 behaves differently). This is what worked for me:
$('body').on('paste', '.select2-input', function (e) {
var pasteData = (e.originalEvent || e).clipboardData.getData('text/plain') || '';
$(this).val(pasteData + ',');
e.preventDefault();
});
Since at the point the event was triggered the value of .select2-input was an empty string, I extractacted the pasted string from the event object. Apparently the default select2 for copying action was still triggering after this, so I had to add e.preventDefault(); to stop it from running and messing up the input.
just run this jQuery which takes the separatoes from options.tokenSeparators directly, and applies for all select2 instances in the page automatically:
$(document).on('paste', 'span.select2', function (e) {
e.preventDefault();
var select = $(e.target).closest('.select2').prev();
var clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
var createOption = function (value, selected) {
selected = typeof selected !== 'undefined' ? selected : true;
return $("<option></option>")
.attr("value", value)
.attr("selected", selected)
.text(value)[0]
};
$.each(
clipboard.split(new RegExp(select.data('select2').options.options.tokenSeparators.map(function (a) {
return (a).replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}).join('|'))),
function (key, value) {
if (value && (!select.val() || (select.val() && select.val().indexOf('' + value) == -1))) {
select.append(createOption(value));
}
});
select.trigger('change');
});
I have the following
Rails HAML:
= select_tag "some-class",
options_for_select([['None', '']], ''),
{ class: 'some-other-class',
'ng-model' => 'someModel',
'ng-options' => 'option.name for option in someList',
'ng-change' => 'updateSelected()'}
Angular Controller:
scope.updateSelected = ->
#logic for updating model lives here. Model updates successfully by using some values defined within scope. Includes the following:
scope.someModel = "some_new_value"
Angular Directive:
SomeClassDirective= ->
restrict: 'C'
link: (scope, element, attrs) ->
monitorFormFields = (newValue, oldValue) ->
console.log "this is the inner function call"
#logic for setting the inner _destroy field lives here
scope.$watch 'someModel', monitorFormFields
However, when the Select List value is changed, 'this is the inner function call' never prints.(it does print when the directive first initializes, ie at page load). My question therefore is: Why isn't the $watch expression triggering, and how do I get it to trigger?
Thanks!
With this HTML:
<select class="some-class" ng-model="someModel"
ng-options="option.name for option in someList"></select>
Here is a directive that will watch for a change to someModel:
myApp.directive('someClass', function () {
return {
restrict: 'C',
link: function (scope, element, attrs) {
var monitorFormFields = function (newValue, oldValue) {
console.log("this is in the inner function call");
}
scope.$watch('someModel', monitorFormFields);
}
}
});
Controller:
$scope.someList = [{ name: 'name1' }, { name: 'name2' }];
Note that you don't need to call a controller method to update someModel -- Angular does that automatically for us because of the ng-model attribute. So, the directive only needs to $watch for a change to that $scope property.
Fiddle.
I would like to from the element fetch a sibling with [_destroy] in the name and set it to either "0" or "1" depending on the value of the select box.
A more Angular approach would be to have model properties control whether "0" or "1" is displayed. E.g., in your controller:
$scope.destroy1 = "0";
$scope.destroy2 = "0";
In your HTML:
<div>{{destroy1}}</div>
<div>{{destroy2}}</div>
In monitorFormFields() you can change the values of these scope properties, and the view will automatically update -- there is no need to "find" siblings or update .val()ues.
Hello I am trying to write a jasmine test for a backbone view and one of its function. I want to test the correct behavior of the function in the case a user checks a checkbox in the rendered view then submit.
Here is the tests :
describe("buildCI()", function() {
describe("with a category selection allowed's quidget model", function() {
it("returns a CoacheeIssue model with the selected categories", function() {
selection_allowed = true;
lcc_selection_allowed = false;
var view = new Rails3DeviseRspecCucumber.Views.CategoryPicker({
collection: categoriesCollection,
answers: answers,
category_ids: category_ids,
credentials: credentialsCollection,
user_hash: user_hash,
selection_allowed: selection_allowed,
lcc_selection_allowed: lcc_selection_allowed
});
// render the view so we can manipulate its DOM elements
view.render();
elDebug = $(view.$el);
// Check programmatically a category checkbox
$(elDebug.find('input.category-checkbox#5061c6a48624da6f4100000a')[0]).prop('checked', true);
// call the buildCI() function and check the result
result = view.buildCI();
console.log(result);
expect(result.get('categories')).toContain('category one');
expect(result.get('categories')).not.toContain('category two');
})
})
Unfortunately the test fails with this message : Expected [ ] to contain 'category one'.
I know it is not a coding error, because it is working in live, I would just like to know how to test it.
Here is the function :
buildCI: () ->
# prepare the category_ids and categories (names) attributes
if #selection_allowed
selectedCategories = []
for checkbox in $('input.category-checkbox')
checkboxEl = $(checkbox)
if checkbox.checked
selectedCategories.push(_.find(#collection.models, (model) ->
model.id == checkboxEl.attr('id')
))
category_names = _.map(selectedCategories, (category) -> category.get('name'))
category_ids = _.map(selectedCategories, (category) -> category.get('_id'))
else
category_names = _.map(#collection.models, (category) -> category.get('name'))
category_ids = _.map(#collection.models, (category) -> category.get('_id'))
return new Rails3DeviseRspecCucumber.Models.CoacheeIssue({
is_solved: false, status: 'active', solution_value_estimate: '',
answers: #answers, categories: category_names, category_ids: category_ids
})
Thanks in advance
Is your selector too strict? I notice that it is:
$(elDebug.find('input.category-checkbox#5061c6a48624da6f4100000a')[0]).prop('checked', true);
but perhaps you only want it to be just:
$(elDebug.find('input.category-checkbox')[0]).prop('checked', true);