I am trying to implement 2 different isotope grids filter + pagination on one page and have issues setting up the second one.
As you can see on my pen, the first one is working and not the second one. I used the same id and class for both grid and think the issue is there but I couldn't manage to update my javascript to make it work!
Could someone help me with that?
Thanks
https://codepen.io/tcosteur/pen/oNWoNWP
here is my js:
function cbChange(obj) {
var cbs = document.getElementsByClassName("filter-item");
for (var i = 0; i < cbs.length; i++) {
cbs[i].checked = false;
}
obj.checked = true;
}
$(document).ready(function() {
// filter items on button click
$('.filter-button-group').on('click', 'li', function() {
var filterValue = $(this).attr('data-filter');
$('.grid').isotope({
filter: filterValue
});
$('.filter-button-group li').removeClass('active');
$(this).addClass('active');
});
})
var itemSelector = ".item";
var $checkboxes = $('.filter-item');
var $container = $('#products').isotope({
itemSelector: itemSelector
});
//Ascending order
var responsiveIsotope = [
[480, 4],
[720, 6]
];
var itemsPerPageDefault = 8;
var itemsPerPage = defineItemsPerPage();
var currentNumberPages = 1;
var currentPage = 1;
var currentFilter = '*';
var filterAttribute = 'data-filter';
var filterValue = "";
var pageAttribute = 'data-page';
var pagerClass = 'isotope-pager';
// update items based on current filters
function changeFilter(selector) {
$container.isotope({
filter: selector
});
}
//grab all checked filters and goto page on fresh isotope output
function goToPage(n) {
currentPage = n;
var selector = itemSelector;
var exclusives = [];
// for each box checked, add its value and push to array
$checkboxes.each(function(i, elem) {
if (elem.checked) {
selector += (currentFilter != '*') ? '.' + elem.value : '';
exclusives.push(selector);
}
});
// smash all values back together for 'and' filtering
filterValue = exclusives.length ? exclusives.join('') : '*';
// add page number to the string of filters
var wordPage = currentPage.toString();
filterValue += ('.' + wordPage);
changeFilter(filterValue);
}
// determine page breaks based on window width and preset values
function defineItemsPerPage() {
var pages = itemsPerPageDefault;
for (var i = 0; i < responsiveIsotope.length; i++) {
if ($(window).width() <= responsiveIsotope[i][0]) {
pages = responsiveIsotope[i][1];
break;
}
}
return pages;
}
function setPagination() {
var SettingsPagesOnItems = function() {
var itemsLength = $container.children(itemSelector).length;
var pages = Math.ceil(itemsLength / itemsPerPage);
var item = 1;
var page = 1;
var selector = itemSelector;
var exclusives = [];
// for each box checked, add its value and push to array
$checkboxes.each(function(i, elem) {
if (elem.checked) {
selector += (currentFilter != '*') ? '.' + elem.value : '';
exclusives.push(selector);
}
});
// smash all values back together for 'and' filtering
filterValue = exclusives.length ? exclusives.join('') : '*';
// find each child element with current filter values
$container.children(filterValue).each(function() {
// increment page if a new one is needed
if (item > itemsPerPage) {
page++;
item = 1;
}
// add page number to element as a class
wordPage = page.toString();
var classes = $(this).attr('class').split(' ');
var lastClass = classes[classes.length - 1];
// last class shorter than 4 will be a page number, if so, grab and replace
if (lastClass.length < 4) {
$(this).removeClass();
classes.pop();
classes.push(wordPage);
classes = classes.join(' ');
$(this).addClass(classes);
} else {
// if there was no page number, add it
$(this).addClass(wordPage);
}
item++;
});
currentNumberPages = page;
}();
// create page number navigation
var CreatePagers = function() {
var $isotopePager = ($('.' + pagerClass).length == 0) ? $('<div class="' + pagerClass + '"></div>') : $('.' + pagerClass);
$isotopePager.html('');
if (currentNumberPages > 1) {
for (var i = 0; i < currentNumberPages; i++) {
var $pager = $('');
$pager.html(i + 1);
$pager.click(function() {
var page = $(this).eq(0).attr(pageAttribute);
goToPage(page);
});
$pager.appendTo($isotopePager);
}
}
$container.after($isotopePager);
}();
}
// remove checks from all boxes and refilter
function clearAll() {
$checkboxes.each(function(i, elem) {
if (elem.checked) {
elem.checked = null;
}
});
currentFilter = '*';
setPagination();
goToPage(1);
}
setPagination();
goToPage(1);
//event handlers
$checkboxes.change(function() {
var filter = $(this).attr(filterAttribute);
currentFilter = filter;
setPagination();
goToPage(1);
});
$('#clear-filters').click(function() {
clearAll()
});
$(window).resize(function() {
itemsPerPage = defineItemsPerPage();
setPagination();
goToPage(1);
});
Related
I developed the store locator using open street map and leaflet. The problem is when I want to type in searchbox it will become lagging to finish the word. That store locator read from the CSV file that has 300++ data. Below is the code for the searchbox:
var locationLat = [];
var locationLng = [];
var locMarker;
var infoDiv = document.getElementById('storeinfo');
var infoDivInner = document.getElementById('infoDivInner');
var toggleSearch = document.getElementById('searchIcon');
var hasCircle = 0;
var circle = [];
//close store infor when x is clicked
var userLocation;
$("#infoClose").click(function() {
$("#storeinfo").hide();
if (map.hasLayer(circle)) {
map.removeLayer(circle);
}
});
var listings = document.getElementById('listingDiv');
var stores = L.geoJson().addTo(map);
var storesData = omnivore.csv('assets/data/table_1.csv');
function setActive(el) {
var siblings = listings.getElementsByTagName('div');
for (var i = 0; i < siblings.length; i++) {
siblings[i].className = siblings[i].className
.replace(/active/, '').replace(/\s\s*$/, '');
}
el.className += ' active';
}
function sortGeojson(a,b,prop) {
return (a.properties.name.toUpperCase() < b.properties.name.toUpperCase()) ? -1 : ((a.properties.name.toUpperCase() > b.properties.name.toUpperCase()) ? 1 : 0);
}
storesData.on('ready', function() {
var storesSorted = storesData.toGeoJSON();
//console.log(storesSorted);
var sorted = (storesSorted.features).sort(sortGeojson)
//console.log(sorted);
storesSorted.features = sorted;
//console.log(storesSorted)
stores.addData(storesSorted);
map.fitBounds(stores.getBounds());
toggleSearch.onclick = function() {
//var s = document.getElementById('searchbox');
//if (s.style.display != 'none') {
//s.style.display = 'yes';
//toggleSearch.innerHTML = '<i class="fa fa-search"></i>';
//$("#search-input").val("");
//search.collapse();
//document.getElementById('storeinfo').style.display = 'none';
//$('.item').show();
//} else {
//toggleSearch.innerHTML = '<i class="fa fa-times"></i>';
//s.style.display = 'block';
//attempt to autofocus search input field when opened
//$('#search-input').focus();
//}
};
stores.eachLayer(function(layer) {
//New jquery search
$('#searchbox').on('change paste keyup', function() {
var txt = $('#search-input').val();
$('.item').each(function() {
if ($(this).text().toUpperCase().indexOf(txt.toUpperCase()) != -1) {
$(this).show();
} else {
$(this).hide();
}
});
});
I dont know what is the cause of the lag in the search box. It is something wrong in code or the csv file? Thank you
Every iteration of $('.item').each is causing a layout change because $(this).hide() or $(this).show() causes the item to removed/added to the DOM as the style is set to display:none back and forth. DOM manipulations and the corresponding layout changes are expensive.
You can consider accumulating the changes and doing one batch update to the DOM using a function like appendChild
In order to export a view to an excel file I use this but the problem is that I can't export the last line generated by sum attributes:
if (children) {
// find only rows with data
view.$el.find('.o_list_view > tbody > tr[data-id]:has(.o_list_record_selector input:checkbox:checked)')
.each(function () {
var $row = $(this);
var export_row = [];
$.each(export_columns_keys, function () {
var $cell = $row.find('td[data-field="' + this + '"]')
var $cellcheckbox = $cell.find('.o_checkbox input:checkbox');
if ($cellcheckbox.length) {
export_row.push(
$cellcheckbox.is(":checked")
? _t("True") : _t("False")
);
}
else {
var text = $cell.text().trim();
export_row.push(text);
}
});
export_rows.push(export_row);
});
}
how can I add it ? is there a way?
Shouldn't var export_row = []; be var export_rows = []; ? (Note the final s)
I am trying to activate keyup event on an input element, the problem is it didn't trigger once I press a key, I have to do another key event to activate it, which is not normal!
Here's my code:
$(".conv").keyup(function(){
var itemId = new Array();
$(".itemId").each(function() {
itemId.push($(this).text());
});
if (itemId.length == 0 || isEmpty($(this).val())) {
$(this).val('0.00');
return false;
}
if (!$.isNumeric($(this).val())) {
alert("Only numeric values are allowed in '" + $(this).parent().parent().find('th').text() + "' field.");
return false;
}
calcShipping();
});
I tried to use on like this, but also not working:
$('body').on("keyup", ".plus", function(){
var itemId = new Array();
$(".itemId").each(function() {
itemId.push($(this).text());
});
if (itemId.length == 0) {
$(this).val('0.00');
return false;
}
calcShipping();
});
Calculate shipping function:
var calcShipping = function() {
if (isEmpty($(".totalCost2").text())) {
$(".totalCost2").text(parseInt($(".totalCost").text()));
}
var plus = 0;
var conv = parseInt($(".conv").val());
var tCost = parseInt($(".totalCost2").text());
var tQty = 0;
var tFinal = 0;
var tLast = 0;
var qty = 0;
var totalCost = 0;
var cost = new Array();
var qtyCost = new Array();
$("#txtItems2").attr('disabled','disabled');
$("#btnReset2").attr('disabled','disabled');
$("#uploadItems").attr('disabled','disabled');
$("#startUpload").attr('disabled','disabled');
$(".plus").each(function(){
if (isEmpty($(this).val())) {
$(this).val('0.00');
}
if (!$.isNumeric($(this).val())) {
alert("Only numeric values are allowed in '" + $(this).parent().parent().find('th').text() + "' field.");
return false;
}
plus += parseInt($(this).val());
});
$(".qty").each(function() {
qtyCost.push(parseInt($(this).text()));
tQty += parseInt($(this).text());
});
$(".cost").each(function() {
cost.push($(this).text());
});
tFinal = plus + tCost;
tLast = tFinal/tQty;
var qty = 0;
$(".cost").each(function(){
qty = parseInt($(this).parent().parent().find($(".qty")).text());
$(this).text(tLast * qty * conv);
qty = 0;
});
for (var i = 0; i < cost.length; i++)
{
totalCost += (cost[i] * qtyCost[i]);
}
$(".totalCost").text(totalCost.toFixed(2));
}
Any advice?
Try the following
$('.conv').on("input", function() {
//do what you need to do here
});
Something like this
I found the problem, I have to recalculate the ".cost" after modifying it, not before, like this:
$(".cost").each(function(){
qty = parseInt($(this).parent().parent().find($(".qty")).text());
var newCost = tLast * qty * conv;
$(this).text(newCost);
qty = 0;
});
$(".cost").each(function() {
cost.push($(this).text());
});
I hacked an isotope combofilter with checkboxes, but here is the problem with the isotope items; They are disappearing when resizing browser window.
I dont why they are not displaying when I change the size of the browser!
Please so help!!
Normaly I use isotope V2. Here in JSFiddle, there is np with the window resizing however I used isotope v1..
I am driving crazy, when items disappeared I need to trigger by clicking a select button, then its going fine.
var $containerii;
var filters = {};
jQuery(document).ready(function () {
var $containerii = $('.isotope').isotope({
itemSelector: '.isotope-item'
});
getContent: '.isotope-item li'
var $filterDisplay = $('#filter-display');
$containerii.isotope();
// do stuff when checkbox change
$('#options').on('change', function (jQEvent) {
var $checkbox = $(jQEvent.target);
manageCheckbox($checkbox);
var comboFilter = getComboFilter(filters);
$containerii.isotope({ filter: comboFilter });
$filterDisplay.text(comboFilter);
});
});
function getContent() {
var items = document.getElementById("containerii")
}
function getComboFilter(filters) {
var i = 0;
var comboFilters = [];
var message = [];
for (var prop in filters) {
message.push(filters[prop].join(' '));
var filterGroup = filters[prop];
// skip to next filter group if it doesn't have any values
if (!filterGroup.length) {
continue;
}
if (i === 0) {
// copy to new array
comboFilters = filterGroup.slice(0);
} else {
var filterSelectors = [];
// copy to fresh array
var groupCombo = comboFilters.slice(0); // [ A, B ]
// merge filter Groups
for (var k = 0, len3 = filterGroup.length; k < len3; k++) {
for (var j = 0, len2 = groupCombo.length; j < len2; j++) {
filterSelectors.push(groupCombo[j] + filterGroup[k]); // [ 1, 2 ]
}
}
// apply filter selectors to combo filters for next group
comboFilters = filterSelectors;
}
i++;
}
var comboFilter = comboFilters.join(', ');
return comboFilter;
}
function manageCheckbox($checkbox) {
var checkbox = $checkbox[0];
var group = $checkbox.parents('.option-set').attr('data-group');
// create array for filter group, if not there yet
var filterGroup = filters[group];
if (!filterGroup) {
filterGroup = filters[group] = [];
}
var isAll = $checkbox.hasClass('all');
// reset filter group if the all box was checked
if (isAll) {
delete filters[group];
if (!checkbox.checked) {
checkbox.checked = 'checked';
}
}
// index of
var index = $.inArray(checkbox.value, filterGroup);
if (checkbox.checked) {
var selector = isAll ? 'input' : 'input.all';
$checkbox.siblings(selector).removeAttr('checked');
if (!isAll && index === -1) {
// add filter to group
filters[group].push(checkbox.value);
}
} else if (!isAll) {
// remove filter from group
filters[group].splice(index, 1);
// if unchecked the last box, check the all
if (!$checkbox.siblings('[checked]').length) {
$checkbox.siblings('input.all').attr('checked', 'checked');
}
}
}
If your using isotope v2, try this:
var $containerii = $('.isotope').isotope({
itemSelector: '.isotope-item',
isResizeBound: true
});
v1.5, this:
ADDENDUM
I don't see anything disappearing, just the col-md-10 shifting down when you resize your window. I changed the layout to avoid the shift and it seems to resize as it should.
jsfiddle
Thank you so much for helps and valuable responses. Finally I solved my problem by using trigger isotope on window resize at the end of the code.
$(window).on('resize', function () {
$containerii = $('.isotope');
triggerIsotope();
});
I'm trying to convert javascript code from CRM 4.0 to CRM 2011.
I'm having problems with a picklist filter.
My function is on the onchange of the parent picklist. It works the first time but the second it erase everything from my child picklist.
This is the part where I suppose to reset the picklist
if(!oSubPicklist.originalPicklistValues)
{
oSubPicklist.originalPicklistValues = oSubPicklist.getOptions();
}
else
{
oSubPicklist.getOptions = oSubPicklist.originalPicklistValues;
oSubPicklist.setOptions = oSubPicklist.originalPicklistValues;
}
And this is the part where i remove all the option not related:
oTempArray is an array with the options that i want to keep. If a check the "oSubPicklist.getOptions.length" the value is the same that my original picklist.
for (var i=oSubPicklist.getOptions.length; i >= 0;i--)
{
if(oTempArray[i] != true)
{
Xrm.Page.getControl("new_product").removeOption(i);
}
}
Ideas?
Edit: I solved declaring a global var with the originalPickList in the onLoad event and:
oSubPicklist.clearOptions();
for (var i=0; i< oSubPicklist.originalPicklistValues.length; i++)
{
for (var j=0; j< oDesiredOptions.length; j++)
{
if (i == oDesiredOptions[j])
{oSubPicklist.addOption(oSubPicklist.originalPicklistValues[i]);}
}
}
Your code is not very clear to me: May be you could paste all your function code for better understanding but:
This is how you get the options from PickList in CRM 2011
var myOptionSet = Xrm.Page.ui.controls.get("new_product") //get Control
var optionsSet = myOptionSet .getAttribute().getOptions(); //get Options
preferredTimeOptionSet.clearOptions(); //Clear all options
//Create a new Option
var opt1 = new Option();
opt1.text = "one";
opt1.value = 1;
//Add Option
myOptionSet.addOption(opt1);
//Remove Option
myOptionSet.removeOption(1);
Good Example here
Here is another way to do Parent/Child picklists:
function dynamicDropdown(parent, child) {
filterPicklist(parent, child);
}
function parentListFilter(parent, id) {
var filter = "";
if (getParentCode(parent) != "") {
filter = getParentCode(parent);
} else {
// No [ ] match
}
return filter;
}
function filterPicklist(parent, child) {
var parentList = Xrm.Page.getAttribute(parent).getValue();
var childListControlAttrib = Xrm.Page.getAttribute(child);
var childListOptions = childListControlAttrib.getOptions();
var childListControl = Xrm.Page.getControl(child);
var codeToFilterListOn = parentListFilter(parent, parentList);
if (codeToFilterListOn != "") {
childListControl.clearOptions();
for (var optionIndex in childListOptions) {
var option = childListOptions[optionIndex];
// Ignore xx and check for Match
if (option.text.substring(0, 2) != "xx" && option.text.indexOf(codeToFilterListOn) > -1) {
childListControl.addOption(option);
}
}
} else {
// Didn't match, show all?
}
}
function getParentCode(parent) {
//Get Parent Code Dynamically from inside [ ]
var filter = "";
var parentValue = Xrm.Page.getAttribute(parent).getText();
if (parentValue && parentValue.indexOf("]") > -1) {
var parentCode = parentValue.substring(parentValue.indexOf("[") + 1, parentValue.indexOf("]"));
if (parentCode) {
filter = parentCode + " | ";
} else {}
}
return filter;
}
See more here: Parent/Child