Select2 nested json parsing not working Rails3 - ruby-on-rails

I'm trying to make select2 working with my ajax loaded json data with nested attributes.
I wanna get something like this http://ivaynberg.github.io/select2/#multi.
eaxmple json:
[{
id: 1,
name: "GroupName",
users: [{id: 1, name: 'UserName'}, {id: 2, name: 'SecondUser}]
}]
On the site they use <optgroup label="GroupName"><option value="1">UserName</opyion></optgroup> and getting the right result.
In my case it displays nesting properly, but I can select only GroupName, but I need to select nested userName and make GrouoName unselectable, only gor informational purposes.
code:
$('#user_tokens').select2({
placeholder: "Search for a user",
minimumInputLength: 0,
tags: true,
multiple: true,
ajax: {
url: "messages/users_data.json",
dataType: 'json',
quietMillis: 100,
data: function(search, page) {
return {
q: search,
per: 3,
page: page
};
},
results: function(data, page) {
return {
results: data,
};
}
},
formatResult: formatResult,
formatSelection: formatSelection,
dropdownCssClass: "bigdrop"
});
formatResult:
var formatUserResult = function(data) {
var optgroup = "";
var users = "";
if (data.name !== undefined) {
data.users.forEach(function(e) {
users += "<li class='select2-results-dept-1 select2-result select2-result- selectable'>" +
"<div class='select2-result-label'>" +
"<span class='select2-match'></span>"+
e.firstname +
"</div>" +
"</li>";
});
optgroup += "<div class='select2-result-label'>" +
"<span class='select2-match'></span>" +
data.name + "</div>" +
'<ul class="select2-result-sub">' + users + '</ul>';
}
return optgroup;
}
The problem is that optgroup must have class: 'select2-result-unselectable'
Dunno what to do with it.

Related

select2 with ajax not displaying results

I'm trying to retrieve suppliers with select2 and ajax.
So this is my js code,
$(document).ready(function(){
$('.supplier_suggestion').select2({
placeholder: 'Search for supplier',
ajax: {
type: 'GET',
url: '/search_supplier',
delay: 250,
data: function(params){
var query = {
q: params.term
}
return query;
},
dataType: 'json',
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.text,
id: item.id
}
})
};
}
}
});});
I got this in my haml (which called the js file above)
%b.tosca XXX
.input-field
= f.text_field :supplier_name, class: "supplier_suggestion browser-default"
= error_for #ro_nonreg, :supplier_name
and this ini search_controller.rb
def search_supplier
search = params[:q]
search_pattern = '%' + search.downcase + '%'
result_raw = Supplier.where('lower(supplier_name) LIKE ? OR lower(shadow_id) LIKE ?', search_pattern, search_pattern)
result = []
result_raw.each do |data|
data_hash = {}
data_hash[:id] = data.shadow_id
data_hash[:text] = data.supplier_name
result << data_hash
end
render_secure_json supplier: result
end
what am i missing here?

How set background color of each level in hierarchical jqgrid

I use free jqgrid(v5.1.1) in my asp.net mvc project.
In my view,I have 5 level hierarchical jqgrid. how can I set background color of header of each level? for example header of first level has "blue" color,second level has "green" color,third level has "light blue" color and....
here is my code:
//************************************fill grid level 1 **********************************
function FillJQueryGrid(ProjectIdVal) {
$("#jqGrid").jqGrid({
url: '#Url.Action("GetCodingCodeSumLists", "Report")' + '?ProjectId=' + ProjectIdVal,// jqgrid_data,
jsonReader: {
repeatitems: false,
root: function (obj) {
return obj.records;
}
},
datatype: "json",
height: 'auto',
page: 1,
colModel: [
{ label: 'Fieco Doc No.', name: 'comp_code', key: true},
{ label: 'Subject', name: 'Comp_Subject' },
{ label: 'Delay', name: 'sum_delay_count' },
],
width:"100%",
loadonce: true,
autowidth: true,
rowNum: 20,
subGrid: true,
subGridRowExpanded: showChildGridrevision,
pager: "#jqGridPager"
});
};
//***********************************fill grid level 2 *******************************************
function showChildGridrevision(parentRowID, parentRowKey) {
var childGridID = parentRowID + "_table";
var childGridPagerID = parentRowID + "_pager";
var childGridURL = '#Url.Action("GetRevisionSumLists", "Report")' + '?CompCode=' + parentRowKey;
$('#' + parentRowID).append('<table id=' + childGridID + '></table><div id=' + childGridPagerID + ' class=scroll></div>');
$("#" + childGridID).jqGrid({
url: childGridURL,
jsonReader: {
repeatitems: false,
root: function (obj) {
return obj.records;
}
},
datatype: "json",
height: 'auto',
width: "100%",
page: 1,
colModel: [
{label:'CompCode_Revision',name:'CompCode_Revision',key:true,hidden:true},
{ label: 'comp_code', name: 'comp_code', hidden: true },
{ label: 'revision', name: 'revision',width:500 },
{ label: 'Delay', name: 'sum_delay_count',width:500 }
],
loadonce: true,
subGrid: true,
subGridRowExpanded: showChildGridTransmital,
pager: "#" + childGridPagerID
});
}
//***********************************fill grid level 3 *******************************************
function showChildGridTransmital(parentRowID2, parentRowKey2) {
debugger;
var childGridID2 = parentRowID2 + "_table";
var childGridPagerID2 = parentRowID2 + "_pager";
var childGridURL2 = '#Url.Action("GetTransmitalSumLists", "Report")' + '?CompCode_Revision=' + parentRowKey2;
$('#' + parentRowID2).append('<table id=' + childGridID2 + '></table><div id=' + childGridPagerID2 + ' class=scroll></div>');
$("#" + childGridID2).jqGrid({
url: childGridURL2,
jsonReader: {
repeatitems: false,
root: function (obj) {
return obj.records;
}
},
datatype: "json",
height:'auto',
page: 1,
colModel: [
{ label: 'CompCode_Revision_Transmital', name: 'CompCode_Revision_Transmital', key: true,hidden:true},
{ label: 'CompCode_Revision', name: 'CompCode_Revision', hidden: true },
{ label: 'transmital no', name: 'trans_ref_no' ,width:200},
{ label: 'transmital subject', name: 'ChkMain_Subject' ,width:400},
{ label: 'transmital date', name: 'trans_date',width:200 },
{ label: 'Delay', name: 'sum_delay_count',width:200 }
],
width:'100%',
loadonce: true,
subGrid: true,
subGridRowExpanded: showChildGridReceiver,
pager: "#" + childGridPagerID2
});
}
//***********************************fill grid level 4 *******************************************
function showChildGridReceiver(parentRowID, parentRowKey) {
debugger;
var childGridID = parentRowID + "_table";
var childGridPagerID = parentRowID + "_pager";
var childGridURL = '#Url.Action("GetReceiverSumLists", "Report")' + '?CompCode_Revision_Transmital=' + parentRowKey;
$('#' + parentRowID).append('<table id=' + childGridID + '></table><div id=' + childGridPagerID + ' class=scroll></div>');
$("#" + childGridID).jqGrid({
url: childGridURL,
jsonReader: {
repeatitems: false,
root: function (obj) {
return obj.records;
}
},
datatype: "json",
page: 1,
colModel: [
{ label: 'CompCode_Revision_Transmital_receiver', name: 'CompCode_Revision_Transmital_receiver', key: true, hidden: true },
{ label: 'receiver_id', name: 'receiver_id',hidden:true },
{ label: 'Receiver Name', name: 'receiver_name',width:500 },
{ label: 'Delay', name: 'sum_delay_count', width: 500 }
],
loadonce: true,
height: '100%',
subGrid: true,
subGridRowExpanded: showChildGridLetter,
pager: "#" + childGridPagerID
});
}
//***********************************fill grid level 5 *******************************************
function showChildGridLetter(parentRowID, parentRowKey) {
debugger;
var childGridID = parentRowID + "_table";
var childGridPagerID = parentRowID + "_pager";
var childGridURL = '#Url.Action("GetLettersOfCodingWithDelayLists", "Report")' + '?CompCode_Revision_Transmital_Receiver=' + parentRowKey;
$('#' + parentRowID).append('<table id=' + childGridID + '></table><div id=' + childGridPagerID + ' class=scroll></div>');
$("#" + childGridID).jqGrid({
url: childGridURL,
jsonReader: {
repeatitems: false,
root: function (obj) {
return obj.records;
}
},
datatype: "json",
page: 1,
colModel: [
{ label: 'DCC_letter_id', name: 'DCC_letter_id', key: true, hidden: true },
{ label: 'CommentLetter No', name: 'Let_no'},
{ label: 'Subject', name: 'Let_subject' ,width:300},
{ label: 'Estimate Date', name: 'estimate_date_of_letter' },
{ label: 'Send Date', name: 'Let_date' },
{ label: 'Delay', name: 'delay_count_of_letter'}
],
loadonce: true,
height: '100%',
subGrid: false,
pager: "#" + childGridPagerID
});
}
First of all, I want to mention, that there are no free jqGrid v5.1.1. It's commercial version, which price you can see under under link, which you see in the comment at the beginning of jquery.jqGrid.min.js: "License: http://guriddo.net/?page_id=103334%22". Free jqGrid is alternative fork of jqGrid, which I develop starting with the end of 2014, after the end of "jqGrid" and renaming the fork to "Guriddo jqGrid JS".
The second important common remark: it's important, that one has no id duplicates on HTML page. Thus one should choose unique id values. In case of usage subgrids one can easy get id duplicates if multiple subgrids are opened. One can solve the problem in very easy way, by usage idPrefix in all subgrids. For example you can use
idPrefix: parentRowKey + "_" // or parentRowKey2 + "_"
Now about your main problem. There are many ways to use background-color to allow the user to see the level of the grid. For example, every subgrid consist of two parts: td.subgrid-cell and td.subgrid-data. One can set background color on td.subgrid-cell. You will have the results like on the picture below
One more option will be setting background color on the column headers of every subgrid. The results will be like
If you would use free jqGrid, then you can use labelClasses property of colModel. You need just add the property labelClasses: "blue" to colModel and to define the following CSS rule:
.ui-jqgrid-labels .blue {
background-color: #b3d9ff;
background-image: none;
}
To add labelClasses: "blue" option to all columns of subgrid you can use `cmTemplate``option of the subgrid:
cmTemplate: { labelClasses: "blue" }
The code of subGridRowExpanded could be the following:
subGridRowExpanded: function (subgridDivId, rowid) {
var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
subgridData = $(this).jqGrid("getLocalRow", rowid).details,
$subgridDataDiv = $("#" + subgridDivId),
$subgridCell = $subgridDataDiv.closest(".subgrid-data").prev(".subgrid-cell");
$subgridCell.addClass("blue"); // set background color on td.subgrid-cell
$subgridDataDiv.append($subgrid);
$subgrid.jqGrid({
idPrefix: rowid + "_",
data: subgridData,
colModel: [
{ name: "c1", label: "Col 1" },
{ name: "c2", label: "Col 2" },
{ name: "c3", label: "Col 3" }
],
cmTemplate: { labelClasses: "blue" }, // set background color on column headers
iconSet: "fontAwesome",
autowidth: true,
autoencode: true,
sortname: "c1"
});
}
One will be need to add CSS rule like the following
.ui-jqgrid .ui-subgrid .subgrid-cell.blue {
background-color: #b3d9ff;
background-image: none;
}
See the demo https://jsfiddle.net/OlegKi/q5j6vnLa/.
If you have to use old jqGrid of Guriddo, then you can't use labelClasses, but you can use setLabel method, for example, to assign class on the column header.

Populate Select2 field in Edit form

I'm a hobbyist developer. I'm using basic Select2 ajax in a new/edit Rails form, and I can't figure out how to re-populate it in the edit form. song_creditor_1 is a string, but it's entered as an id of Fan model.
form:
<%= f.input :song_creditor_1, label: 'Song Creditor 1', as: :select, input_html: { id: "song_creditor_1", include_hidden: false } %>
script
function templateDropDownFormat (item) {
return item.text;
}
function templateSelectionFormat (item) {
return item.text;
}
$("#song_creditor_1").select2({
placeholder: "Search",
ajax: {
url: "/songs",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
return {
results: $.map(data, function(cnut) {
return {
text: cnut.name + ", " + cnut.city + ", " + cnut.country + " (" + cnut.account_type + ")",
id: cnut.id,
};
}),
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
templateResult: templateDropDownFormat, // omitted for brevity, see the source of this page
templateSelection: templateSelectionFormat// omitted for brevity, see the source of this page
});
Well, I'm just a hobbyist, and this is my first website, so this answer isn't pretty but it's how I resolved it. The issue was having to re-populate the data in the field if there was an error on the form, so I just pulled that particular attribute out during the 'create' and called it #creditor1.
var $select1 = $('#song_creditor_1');
function templateDropDownFormat (item) {
return item.text;
}
function templateSelectionFormat (item) {
return item.text;
}
$select1.select2({
ajax: {
url: "/songs",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
return {
results: $.map(data, function(cnut) {
return {
text: cnut.name + ", " + cnut.city + ", " + cnut.country + " (" + cnut.account_type + ")",
id: cnut.id,
};
}),
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
templateResult: templateDropDownFormat, // omitted for brevity, see the source of this page
templateSelection: templateSelectionFormat// omitted for brevity, see the source of this page
});
<% if params[:action] === "edit" && #creditor1_real || params[:action] === "update" && #creditor1_real %>
var $option1 = $('<option selected><%= #creditor1_real.name %>, <%= #creditor1_real.city %>, <%= #creditor1_real.country %></option>').val("<%= #creditor1_real.id %>");
$select1.append($option1).trigger('change');
<% elsif params[:action] === "create" && #creditor1 || params[:action] === "new" && #creditor1 %>
var $option1 = $('<option selected><%= #creditor1.name %>, <%= #creditor1.city %>, <%= #creditor1.country %></option>').val("<%= #creditor1.id %>");
$select1.append($option1).trigger('change');
<% else %>
var $option1 = $('<option selected>Search</option>');
$select1.append($option1).trigger('change');
<% end %>
for me, i found solution to just find and plucking model in select options, while keeping the ajax source on js side
<%= f.select :song_creditor_1, Song.where(song_id: song.id).pluck(:song_name, :id), {}, class: 'your-select-2-class' %>
you can select all from your model, but in my case it slowing page load

jquery select2 return json result name

I am new in jquery select2, in result return id, text and name where id is value I know how to get return id(value) with x$("inputBox").val();. but I want get return name in jquery-select2.
Is there any method to get the return name?
x$("#{id:city_combo_box}").select2({
placeholder:"Select City",
allowClear:true,
minimuminputLength:2,
templateResult: formatRepo,
escapeMarkup: function (markup) {return markup},
templateSelection: formatRepoSelection,
multiple:false,
ajax: {
url:ajaxurl,
dataType:"json",
data: function(params){
pp = params.term;
return{
startKey: pp,
page: params.page,
count: 10
};
},
processResults: function (data, params){
var k = data.viewentry;
console.log(k);
params.page = params.page;
return {
results: $.map(k, function(obj) {
return {id: (obj.entrydata[1].text[0]), text: obj.entrydata, name: (obj.entrydata[0].text[0])};
})
};
}
}
}).on("change", function(e){ x$("#{id:claim_limit_text}").val(x$("#{id:city_combo_box}").val(id));
}).trigger("change");
})
The only solution I came across is this:
html
<div id="ddWrapper1">
<select id="dd1"></select>
</div>
js
$(document).ready(function() {
var ddDate = [{
id: 1,
text: 'some item'
}, {
id: 2,
text: 'even more items'
}, {
id: 3,
text: 'oh no'
}, {
id: 4,
text: 'that is a realy long item name...'
}];
$('#dd1').select2({
data: ddDate,
allowClear: true,
multiple: true,
placeholder: '[dd1] select some items'
});
$('#dd1').on('change', function() {
console.log($('#dd1').data('select2').$selection[0].innerText);
})
});
But I have to admit that the result is not the nicest.

why jquery autocomplete doesnt work on https (secure pages)?

I am trying to make jquery autocomplete to be work on https (secured pages) pages but its not showing any dropdown.
I searched on this issue and found that its security issue.
can any one tell me how to turn on this autocomplete dropdown on https pages.
here is my code to jquery autocomplete :
function zipAutoCompletet(prefix) {
jQuery("#" + prefix + "_zip").autocomplete({
source: function (request, response) {
jQuery.ajax({
url: "http://ws.geonames.org/postalCodeSearchJSON",
dataType: "jsonp",
data: {
style: "full",
maxRows: 12,
postalcode_startsWith: request.term
},
success: function (data) {
response(jQuery.map(data.postalCodes, function (item) {
return {
label: item.placeName + (item.adminCode1 ? ", " + item.adminCode1 : "") + ", " + item.postalCode + ", " + item.countryCode,
value: item.postalCode
}
}));
jQuery('.ui-autocomplete').css('width', '188px');
}
});
},
minLength: 2,
select: function (event, ui) {
var myString = new String(ui.item.label);
var address = myString.split(',')
jQuery('#' + prefix + '_city').val(address[0]);
jQuery('#' + prefix + '_city').addClass('activated');
jQuery('#' + prefix + '_city').trigger('change');
jQuery('#' + prefix + '_city').parents('.row').removeClass('error-row')
jQuery('#' + prefix + '_city').parents('.row').addClass('ok-row')
var countryCode = address[3] ? address[3] : address[2]
countryCode = jQuery.trim(countryCode);
var countryName = jQuery('#' + prefix + '_country option[value="' + jQuery.trim(countryCode) + '"]').text()
jQuery('#countryContainer .jqTransformSelectWrapper span').html(countryName)
jQuery('#countryContainer .jqTransformSelectWrapper').addClass('selected-jqtranform');
jQuery('#' + prefix + '_country').parents('.row').addClass('ok-row')
jQuery('#' + prefix + '_country').parents('.row').removeClass('error-row')
jQuery('#' + prefix + '_country').val(jQuery.trim(countryCode))
var stateCode = address[2] ? address[1] : '';
stateCode = jQuery.trim(stateCode)
if (countryCode == 'US') {
var base = base_url;
base = base.replace("https", "http");
jQuery.ajax({
url: base + "/getStateName",
dataType: "jsonp",
data: {
stateCode: stateCode
},
success: function (data) {
stateName = data
jQuery('#jc_state').val(stateName);
jQuery('#jc_state').addClass('activated');
jQuery('#jc_state').parents('.row').removeClass('error-row')
jQuery('#jc_state').parents('.row').addClass('ok-row')
jQuery('#jc_state').trigger('change');
formValidate();
}
});
} else {
stateName = stateCode
jQuery('#jc_state').val(stateName);
jQuery('#jc_state').addClass('activated');
jQuery('#jc_state').parents('.row').removeClass('error-row')
jQuery('#jc_state').parents('.row').addClass('ok-row')
jQuery('#jc_state').trigger('change');
formValidate();
}
jQuery('#' + prefix + '_zip').parents('.row').addClass('ok-row')
jQuery('#' + prefix + '_zip').parents('.row').removeClass('error-row');
},
open: function () {
jQuery(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
jQuery(this).removeClass("ui-corner-top").addClass("ui-corner-all");
},
change: function (event, ui) {
if (ui.item === null) {
jQuery("#" + prefix + "_zip").parents('.row').removeClass('ok-row');
jQuery("#" + prefix + "_zip").parents('.row').addClass('error-row');
$("#" + prefix + "_zip").val('');
}
}
});
}
I am using above code for zipcode field.This code works fine on non-https pages it works fine but when I tried it with https pages it doesnt shows.
any solutions are welcome.
As I looked into the service provider they are supporting jsonp and the following sample worked
$("input").autocomplete({
source: function (request, response) {
$.getJSON("http://ws.geonames.org/postalCodeSearchJSON?callback=?",
{ 'postalcode_startsWith': request.term, maxRows: 12, style: "full" },
function(data) {
if(data.postalCodes){
var x = $.map(data.postalCodes, function(v, i){
console.log(v)
return {
label: v.placeName + ' - ' + v.postalCode,
v: v.postalCode
}
});
response(x);
}
}
);
}
});
Demo: Fiddle

Resources