Select2 doesn't show options - javascript

I'm currently testing Select2.js in my ASP.NET MVC project.
The first test on a "normal" view just worked fine but now I'm trying to add this to a select box inside a partial view that gets loaded on Ajax Call and then displayed inside a <div> on the normal view page.
The code to generate the dropdown looks like this:
#Html.DropDownList("addRole",
new SelectList(ViewBag.availableRoles, "Id", "Name"),
"Rolle auswählen",
new { #name="addRole", #class = "form-control" }
)
And on the end of the partial view file I added the following:
$(document).ready(function () {
//var data = [{ id: 1, text: "Test" }];
$("#addRole").select2({
//data: data
});
});
It looks like it works because of the look of the select box changes but when I try to open it, it just shows nothing. Same happens when I uncomment the data variable code above.
It just doesn't show anything to me and I don't know why.
I've already tried to add the JavaScript code to $(document).ajaxComplete or in the success function from the AJAX call but it doesn't change anything.

I got the answer now.
The problem was not that the select2 element has no items, the problem was the given items did not show up. So I thought about why didn´t they show up and found out that I´m really stupid.
It did show up, but I can´t see it because of the z-index. My popup window got a z-index of 20k so the dropdown list was behind the window.
So to solve this just add:
.select2-dropdown {
z-index:99999;
}
Or add a dropdownCssClass to the select2 settings with the given z-index like this:
.select2-dropdown.increasezindex {
z-index:99999;
}
JS:
$(document).ready(function () {
$("#addRole").select2({
dropdownCssClass:'increasezindex'
});
});

In my case, I was displaying a select2 on a pop-up element and this causes the dropdown to disappear because it is attached by default to the <body> element.
Select2 troubleshooting guide highlights a similar issue with Bootstrap modals.
To overcome this problem I had to use the dropdown placement option provided,
let $select = $('select'),
$parent = $select.parent();
$select.select2({
dropdownParent: $parent
});

Related

Dynamically loaded JS needs to be clickable just like it's in the html

My page fires off an ajax query, where the MySQL Db is queried and the results are returned. (all successful).
Those results are formatted for output as a shopping gallery/catalogue and also as an accordion filter menu. So I can filter the shopping catalogue display. eg say I want to see only items that are red.
All is working so far.
My problem is with the filter accordion menu - dynamically created in js.
When I click on any selectable item in the tab-content, nothing happens. This means the parameter that should be sent, isn't being sent.
If I hard code the accordion filter or even load it with my server-side language, into the html directly, the filtering does send off the parameter and so the shopping catalogue is adjusted accordingly but, in that scenario, I am unable to dynamically change the filter menu.
I think the code I shall post below is the relevant code that recognises changes in the originally loaded content and fires off the ajax but (I think) it doesn't understand any changes to textboxes in the dynamically loaded content.
Please help me to understand what I need to add that will make dynamically loaded content fire-off to the ajax calls.
var $checkboxes = $("input:checkbox");
function update_nav_filter(opts) {
$.ajax({
type: "POST",
url: "/php-queries/product-filter-query.php",
dataType: 'json',
cache: false,
data: {
filterOpts: opts
},
success: function(records) {
//console.log(records);
//alert('SUCCESS!');
// alert(records);
$('#filters_div').html(makeFilter(records));
}
});
}
$checkboxes.on("change", function() {
//alert('there is a change is checkbox status'); // working on page load but not when any checkbox is clicked-on
var opts = getCatalogueFilterOptions();
updateCatalogue(opts);
update_nav_filter(opts);
});
$checkboxes.trigger("change");
Any help greatly appreciated.
I have created an event listener.
Following page-load, I select an item in the JS generated nav filter. eg pedal_bins in the sub_category section. I am then shown a display of pedal_bins. :)
Then I select 'kettles', another sub_category but I can only see the last sub_category that I click on. The pedal_bins disappear.
How best can I build and remove items with a single click? Store in a session parameter and then
a. remove the latest click if it matches whats in the session
b. add the latest click if its not already in the session
Then submit whatever the array is at that stage?
Or, is there a better way to run this?
Here's the listeneer
enter code here
document.getElementById("filtering_div").addEventListener("click",function(e) {
// e.target was the clicked element
if (e.target && e.target.matches("input")) {
var parameter = e.target.id;
//console.log("Anchor element", parameter , " was clicked" );
var opts = getCatalogueFilterOptions(parameter);
console.log(opts);
// update_nav_filter(opts);
updateCatalogue(opts);
}
});
You have a "delegation" problem. When you create a dynamic element, in order to be able to act on the newly created element, you have to reference it as a child element that was originally loaded with the DOM.
For example, if you have an element called <div id="top"></div> and you create a dynamic element, let's say <button id="test">Click</button> in there, you'll have to refer to that div when adding an event listener.
$("#top").on('click', '#test', function(){
//event related code goes here.
});
Here is a fiddle I created that explains the whole thing with some examples.
If you have any questions about it, please let me know.

Filterizr, applying a filter on initial load

I am using Filterizr for a portfolio.
http://yiotis.net/filterizr/#docs
I have 5 categories, which I have buttons for, that apply filters on click.
I am initialising with the following code:
<script>
var filterizd = $('.filtr-container').filterizr({
layout: 'packed'
});
</script>
The filters all work perfectly.
But, when the page initially loads, no filters are applied, and so all the images load and it's far too many.
I would like to have the script load one of my filters when the page initially loads - so prior to any of the filter buttons actually clicked:
data-filter="1"
I suspect that something could be added to the script options along with my layout option, but I couldn't see anything on the page documentation.
Appreciate any help please
You need to set the initial filter in the options object to the category you want to display on init, just like this:
<script>
var filterizd = $('.filtr-container').filterizr({
filter: 1,
layout: 'packed'
});
</script>
This would initialize your gallery with category nr 1 set to active.

Need help to target / modify custom data attribute

I am working on a website/webshop in WordPress with Woocommerce and tries to add a quantity field next to the 'add to cart' button.
I found this article/tutorial:
How to add quantity to product archives in WooCommerce (and keep ajax) - Christian Varga
http://christianvarga.com/how-to-add-quantity-to-product-archives-in-woocommerce-and-keep-ajax/
It got two small snippets - The first will work correct after copy/paste in my function.php file.
The second is some javascript code which will make the quantity field work together with the 'add to cart' button.
This is the code:
$('.input-text.qty', 'ul.products').on('change', function() {
$(this).closest('div').next('a').attr('data-quantity', $(this).val());
});
When I insert the javascript code nothing happens. It is because I use a custom theme (Avada) which has a different structure I guess.
This was also written on the tutorial:
*Note: This works with WooCommerce’s default HTML structure, but if you’re using a custom theme the HTML structure might be different, so
you’ll need to modify this script to suit.
Here is the link to my page:
http://frisk-matic.identitest.dk/kaffe/
I tried to target my 'add to cart' button but I cannot get it to work and I am not that skilled when it comes to Javascript.
Can someone help me? I would be so glad if I could get a little understanding how this code works.
I know that the first line is to select the quantity field we added and the products div and the result is to change the data-quantity attribute for the button.
Best regards
Samz3n
Try it like this
$('.input-text.qty').on('change', function() {
$(this).parent().next('a.add_to_cart_button').attr('data-quantity', $(this).val());
});
The problem is that your html markup is not the same with this template. I've inspected the markup and write some jQuery code. I think it will do the thing for you! :)
$('.quantity').find('input[type="number"]').on('change',function(){
$(this).parent().next('.product-buttons').find('.add_to_cart_button').data('quantity',$(this).val());
});
u might have some name collisions with your jQuery library, u can try this
var $ = jQuery;
$('.quantity').find('input[type="number"]').on('change', function () {
var value = $(this).val();
var button = $(this).parent().next('.product-buttons').find('.add_to_cart_button');
button.attr('data-quantity', value);
});
or better, use this until you fix naming collisions with jQuery
jQuery('.quantity').find('input[type="number"]').on('change', function () {
var value = jQuery(this).val();
var button = jQuery(this).parent().next('.product-buttons').find('.add_to_cart_button');
button.attr('data-quantity', value);
});

How to rebind a Kendo ListView after changing template

I'm attempting to rebind the listview data after changing the template, based on a DropDownList value. I've included a JSFiddle for reference. When I rebind currently the values in the template are undefined.
Thanks!
JSFiddle link
I was thinking the best way to handle it would be in the 'select' or 'change' function:
var cboDetailsCategory = $("#detail").kendoDropDownList({
data: [
"All",
"Customer",
"Location",
"Meter",
"Other"],
select: function (e) {
var template = $("#" + e.item.text()).html();
console.log("template", template);
$("#details").html(template);
},
change: function (e) {
},
please refer to the JSFiddle link and this graphic as a visual
Here is a lengthier workflow:
User completes a name search and clicks a search button.
Name results are populated in a listview, rendered individually as button controls using a template.
User then clicks one of the name results (shown as the button text).
A dropdownlist of categories ('All' <--default , 'Location', 'Customer'...) gives the user the ability to target what subject of data they want to see. 'All' is the default, showing all details about the selected name.
So by default the 'All' template is populated.
If user wants to see the 'Location' details (template) they select it from the dropdownlist.
The template shows but the values are all blank. The only way to populate it is to click the name (button) again.
I want to remove the need for having to re-click the button (name) to populate the template ('Location', etc...).
I have put together a JSFiddle showing the structure. Though due to the data being private and served over secure network I cannot access it.
Refer to JSFiddle:
I believe the issue is that the onclick event grabs the data-uid and passes it to the initial default template (named 'All' but it's not included in code as it's lengthy). When the user changes the dropdownlist (cboDetailsCategory) and selects a new template I lose the data.
Thanks for your help. I'm really stuck on this and it's a current show stopper.
There isn't an officially supported way to change templates, without destroying the listview and rebuilding it. However, if you don't mind poking into into some private api stuff (be warned I can't guarantee that kendo won't break it without telling you) you can do this
var listview = $("#MyListview").getKendoListView();
listview.options.template = templateString;
listview.template = kendo.template(listview.options.template);
//you can change the listview.altTemplate the same way
listview.refresh(); //redraws the elements
if you want to protect against unknown API changes you can do this, which has A LOT more overhead, but no risk of uninformed change (untested!)
var listview = $("#MyListview").getKendoListView(),
options = listview.options;
options.dataSource = listview.dataSource;
listview.destroy();
$("#MyListview").kendoListView(options);
Here's the solution, thanks for everyone's help!
JSFiddle Link
The issue was where I was setting the bind:
$("#list").on("click", ".k-button", function (e) {
var uid = $(e.target).data("uid");
var item = dataSource.getByUid(uid);
var details = dropdown.value();
var template = $("#" + details).html();
$("#details").html(template);
kendo.bind($("#details"), item);
currentData = item;
});

Using the same JQuery tokeninput box multiple times on a page

I am using Jquery TokenInput in my rails app to help users quickly input information. Each user has a profile with many items of the same class on it, call them college_items. Each college_item has its own edit link, which pops up a modal with the appropriate edit form for the modal.
I followed Ryan Bates's screencast and got TokenInput working properly using the following code:
In application.js:
$(function() {
$("#education_major_tokens").tokenInput("/majors.json", {
theme: "facebook"
})
});
In my view:
<%= f.text_field :major_tokens %>
In my model:
def major_tokens=(ids)
self.major_ids = ids.split(",")
end
The problem I'm running into is that this same field appears in each edit form, so in the edit form for the first item everything works perfectly, but in the edit form for any other item the javascript is not initialized. My question is how can I change the javascript to initialize each time this form element appears, not just the first?
EDIT:
I thought something like this might be the solution:
$(function() {
$("#education_major_tokens").each(function(){
$(this).tokenInput("/majors.json", {
theme: "facebook"
})
});
});
but it still isn't working for me. Anyone out there have any ideas?
EDIT 2:
Figured this out finally. See my edit above, only instead of using #education_major_tokens, I set each input to have :class => "major_input" and changed "#education_major_tokens" in the code to ".major_input"
I think this is a bit late, but try to assign a class to your token field
<input class="yourtokenfield" type="text" />
After that use this
$(function() {
$(".yourtokenfield").each(function(){
$(this).tokenInput("/majors.json", {
theme: "facebook"
})
});
});
I think your problem is due to improper name for class, and remember ID must only appear once in your HTML document.

Categories