Masonry filter + infinite scroll issue - filtering

I built jQuery Masonry layout with infinite scroll and filtering.
My problem is that when a filter clicked before scrolling, the content loaded with infinite scroll is not filtered.
Is there any way to fix it?
Here is the link to check: http://www.jcvergara.com/working/
Here is the full masonry code:
$(document).ready(function(){
var $container = $('.container');
// initialize
$container.masonry({
columnWidth: 250,
itemSelector: '.item',
isFitWidth: true
});
$container.masonry( 'on', 'layoutComplete', function() {
$('.right-line').css('height', $('.container').height());
});
$('.right-line').css('height', $('.container').height());
// infinite scroll
var $container = $('#content');
$container.infinitescroll({
navSelector : "nav.posts-navigation",
nextSelector : "div.nav-previous a:first",
itemSelector : "#content div.item",
},
// trigger Masonry as a callback
function( newElements ) {
var $newElems = $( newElements );
$container.masonry( 'appended', $newElems );
// open posts in ajax
$('.post-link').click(function(){
$('.openarticle').css('display', 'block');
var post_link = $(this).attr('href');
$('#openthis').html('<div class="title"><h2>Loading..</h2><div class="text"></div>');
$('#openthis').load(post_link);
$('<a></a>', {
text: 'Close',
class: 'close',
id: 'close',
href: '#'
})
.prependTo($('.openarticle .main'))
.click(function() {
$('.openarticle').css('display', 'none');
$('#close').remove();
});
return false;
});
}
);
// filtering
$(".cat-item a").click(function(e) {
e.preventDefault();
var cut_url = "http://www.jcvergara.com/category/";
var group = $(this).attr('href');
group = group.replace(cut_url, '').slice(0,-1);
var group_class = "." + group;
$(".cat-item a.active").removeClass('active');
$(this).addClass('active');
if(group != "all") {
$(".item").hide();
$(group_class).show();
$container.masonry();
} else {
$(".item").show();
$container.masonry();
}
});
});

Try using "on" for your click function:
// filtering
$(".cat-item a").on( "click",function (e) {
e.preventDefault();
var cut_url = "http://www.jcvergara.com/category/";
var group = $(this).attr('href');
group = group.replace(cut_url, '').slice(0,-1);
var group_class = "." + group;
$(".cat-item a.active").removeClass('active');
$(this).addClass('active');
if(group != "all") {
$(".item").hide();
$(group_class).show();
$container.masonry();
} else {
$(".item").show();
$container.masonry();
}
});

Related

SAPUI5 SmartTable pressItem event is triggered twice

I have the issue that the pressItem event is triggered twice at smarttable ( sapui5).
The smarttable has type ResponsiveTable.
onAfterRendering : function(){
var tTable = this.byId("LineItemsSmartTable");
var oTable = this.byId("LineItemsSmartTable").getTable();
oTable.setMode(sap.m.ListMode.SingleSelectMaster);
oTable.onAfterRendering = function(){
this.attachItemPress(function(oEvent){ alert( "Pressed" ); });
};
// var fnItemPress = function(){ alert("press2") };
tTable.attachDataReceived(function(){
var aItems = oTable.getItems();
if(aItems.length === 0 ) return;
$.each(aItems, function(oIndex, oItem) {
//oItem.detachPress(fnItemPress);
oItem.setType("Active");
// oItem.attachPress(fnItemPress);
});
});
}
If onAfterRendering is not being called already onInit then reconsider renaming the function oTable.onAfterRendering.
onAfterRendering is already called in the controller lifecycle, you could try creating a new function and then calling that in onAfterRendering.
See this answer
onAfterRendering: function() {
this.tableItems();
},
tableItems: function() {
var tTable = this.byId("LineItemsSmartTable");
var oTable = this.byId("LineItemsSmartTable").getTable();
oTable.setMode(sap.m.ListMode.SingleSelectMaster);
oTable.attachItemPress(function(oEvent) {
alert("Pressed");
});
tTable.attachDataReceived(function() {
var aItems = oTable.getItems();
if (aItems.length === 0) return;
$.each(aItems, function(oIndex, oItem) {
oItem.setType("Active");
});
});
}

Fire BarcodeScannerButton after View loads

I have implemented a scanner button on my Fiori/UI5 application. I used sap.ndc.BarcodeScannerButton and created that button on the controller (I cannot seem to create the button on my view.xml).
Anyway, I need to fire this button after the view loads. I have a master-detail application. The scanner button is on the master view ofcourse.
First thing I did was call the button itself. But my first problem is that the button does not accept an id as a parameter. It tells me that app cannot accept duplicate id. So what I did was just look for the button id. I was able to locate it (e.g. _button9) but whenever I call it via sap.ui.getCore.byId() there are times that it returns "undefined." That's why I cannot call firePress();
Another problem I have is where to put this firePress() method. I tried to put it on method onAfterRendering() assuming that again due to the undefined button I cannot call the method firePress(). I have tried putting it on other methods like after the data has been successfully called by using method attachRequestCompleted. No luck.
Below is the code
/*
* Copyright (C) 2009-2014 SAP SE or an SAP affiliate company. All rights reserved
*/
jQuery.sap.require("sap.ca.scfld.md.controller.ScfldMasterController");
jQuery.sap.require("ui.s2p.srm.sc.create.util.Formatter");
jQuery.sap.require("sap.ndc.BarcodeScannerButton");
var counter = 0;
sap.ui.controller("ui.s2p.srm.sc.create.SRM_SC_CREExtension.view.S2Custom", {
onInit: function() {
sap.ca.scfld.md.controller.ScfldMasterController.prototype.onInit.call(this);
this.oBundle = this.oApplicationFacade.getResourceBundle();
this.isRoot = true;
this.oRouter.attachRouteMatched(function(e) {
if (e.getParameter("name") === "master" && !this.isRoot && Object.keys(e.getParameter("arguments")).length === 0) {
var d = sap.ui.core.routing.History.getInstance().getDirection("shoppingCartCheckout/" + this.tempCartId);
if (d === "Unknown") {
this.isRoot = true;
this._oControlStore.oMasterSearchField.clear()
} else {
if (this.getList() !== null) {
var i = this.getList().getSelectedItem();
if (i !== null) {
//alert("setListGo");
this.setListItem(i);
}
}
}
}
this.isRoot = (this.isRoot) ? false : this.isRoot;
}, this);
// alert(sap.ui.getCore().byId("productScanButton"));
this.onBarcodeScanning();
this.setEmptyCart(true);
this.showAllProducts(); //added by salduam to show all products
},
backToList: function() {
//alert("back");
},
getDefaultUserSettings: function(r) {
var o = function(D, R) {
this.tempCartId = D.results[0].TEMP_CART_ID;
if (!jQuery.device.is.phone) {
if (r) {
this.oRouter.navTo("noData", {
viewTitle: "DETAIL_TITLE",
languageKey: "NO_ITEMS_AVAILABLE"
}, true)
} else {
this.navToEmptyView()
}
}
};
var d = this.oApplicationFacade.getODataModel("getdefusrset");
d.read("DefaultUserSettings?ts=" + Date.now(), null, null, true, jQuery.proxy(o, this), jQuery.proxy(this.onRequestFailed, this))
},
applySearchPatternToListItem: function(i, f) {
if (f.substring(0, 1) === "#") {
var t = f.substr(1);
var d = i.getBindingContext().getProperty("Name").toLowerCase();
return d.indexOf(t) === 0
} else {
return sap.ca.scfld.md.controller.ScfldMasterController.prototype.applySearchPatternToListItem.call(null, i, f)
}
},
getHeaderFooterOptions: function() {
var o = {
sI18NMasterTitle: "MASTER_TITLE",
buttonList: []
};
return o
},
isBackendSearch: function() {
return true
},
//call startReadListData with parameter wildcard
showAllProducts: function(e) {
var startSearchText = "*";
this.startReadListData(startSearchText);
//alert("called");
},
applyBackendSearchPattern: function(f, b) {
//added by salduam
//if search field is blank, automatically call showAllProducts
if (f == "") {
this.showAllProducts()
};
if (f != "" && f != null) {
this.startReadListData(f)
} else {
this.setEmptyCart(false)
}
},
startReadListData: function(f) {
var o = function(D, r) {
var m = new sap.ui.model.json.JSONModel(D.results);
this.getView().setModel(m);
this.getList().destroyItems();
this.getList().bindAggregation("items", {
path: "/",
template: this.oTemplate.clone(),
filter: [],
sorter: null
});
this.registerMasterListBind(this.getList());
};
var e = encodeURIComponent(f);
//console.log("EEEE-----"+ e);
var d = this.oApplicationFacade.getODataModel();
//console.log(d);
d.read("CATALOG_ITEM?$filter=startswith(description,'" + e + "')&$top=20", null, null, true, jQuery.proxy(o, this), jQuery.proxy(this.onRequestFailed,
this));
},
setListItem: function(i) {
// alert("onClick");
var b = i.getBindingContext();
var m = b.oModel.oData[parseInt(b.sPath.split('/')[1])];
this.oRouter.navTo("detail", {
tempCartId: this.tempCartId,
contextPath: b.getPath().substr(1)
}, true);
var c = sap.ui.core.Component.getOwnerIdFor(this.oView);
var C = sap.ui.component(c);
C.oEventBus.publish("ui.s2p.srm.sc.create", "refreshDetail", {
data: m
});
},
setEmptyCart: function(r) {
var e = new sap.ui.model.json.JSONModel({
results: []
});
this.oRouter.navTo("noData", {
viewTitle: "DETAIL_TITLE",
languageKey: "NO_ITEMS_AVAILABLE"
}, true);
this.getView().setModel(e);
this.oTemplate = new sap.m.ObjectListItem({
type: "{device>/listItemType}",
title: "{matnr}",
press: jQuery.proxy(this._handleItemPress, this),
number: "{parts:[{path:'itm_price'},{path:'itm_currency'}],formatter:'ui.s2p.srm.sc.create.util.Formatter.formatPrice'}",
numberUnit: "{itm_currency}",
attributes: [new sap.m.ObjectAttribute({
text: "{description}"
})],
});
this.getList().bindAggregation("items", {
path: "/results",
template: this.oTemplate,
filter: [],
sorter: null,
});
this.registerMasterListBind(this.getList());
this.getDefaultUserSettings(r)
},
onRequestFailed: function(e) {
jQuery.sap.require("sap.ca.ui.message.message");
sap.ca.ui.message.showMessageBox({
type: sap.ca.ui.message.Type.ERROR,
message: e.message,
details: e.response.body
})
},
onExit: function() {},
onBarcodeScanning: function(oEvent) {
var productScanButton = new sap.ndc.BarcodeScannerButton({
provideFallback: "{/btnFallback}",
width: "100%",
scanSuccess: function(oEvent) {
var barcodeID = oEvent.getParameter("text");
sap.m.MessageToast.show(barcodeID);
var searchField = sap.ui.getCore().byId("__field3");
searchField.setValue(barcodeID);
searchField.fireSearch();
}
});
this.getView().byId("barCodeVBox").addItem(productScanButton);
},
onAfterRendering: function(oEvent) {},
onBeforeRendering: function() {}
});
For placing the fire() method. Are you trying to display a pop-up barcode reader? something similar to the pop-up of the app "SD_SO_CRE" (where customer selection dialog is load before master view).
they do not solve the task with fire()...

How could I use tinyMCE when editing a SlickGrid column?

I would like to use tinyMCE with a custom Slick Editor outside of the table, or inside a dialog. It's just to enable rich text editing.
Can I use this external plugin for a custom Slick Editor? I have not seen any example of usages like this.
Is there any potential problems using this two plugins at the same time (injecting conflicting HTML for example or preventing some firing events)?
Use a jquery alias "jQuery_new" with a compatible version
Register the new editor "TinyMCEEditor" & Add it into slick.editors.js
Use it like this {id: "column2", name: "Year", field: "year", editor: Slick.Editors.TinyMCE}
jQuery_new.extend(true, window, {
"Slick": {
"Editors": {
(..)
"TinyMCE": TinyMCEEditor
}
}});
function TinyMCEEditor(args) {
var $input, $wrapper;
var defaultValue;
var scope = this;
this.guid = function () {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4();
},
this.init = function () {
var $container = jQuery_new(".container");
var textAreaIdString = 'rich-editor-'+guid();
$wrapper = jQuery_new("<DIV ID='rds-wrapper'/>").appendTo($container);
$input = jQuery_new("<TEXTAREA id=" + textAreaIdString + "/>");
$input.appendTo($wrapper);
jQuery_new("#" +textAreaIdString).val( args.item[args.column.field] );
var _this = this;
tinymce.init({
selector: "#"+textAreaIdString,
forced_root_block : "",
plugins : "save image imagetools",
toolbar: 'undo redo | styleselect | bold italic | link image | save',
save_onsavecallback: function() {
jQuery_new("#" +textAreaIdString).val( this.getContent() );
_this.save();
}
});
$input.bind("keydown", this.handleKeyDown);
scope.position(args.position);
$input.focus().select();
};
this.handleKeyDown = function (e) {
if (e.which == jQuery_new.ui.keyCode.ENTER && e.ctrlKey) {
scope.save();
} else if (e.which == jQuery_new.ui.keyCode.ESCAPE) {
e.preventDefault();
scope.cancel();
} else if (e.which == jQuery_new.ui.keyCode.TAB && e.shiftKey) {
e.preventDefault();
args.grid.navigatePrev();
} else if (e.which == jQuery_new.ui.keyCode.TAB) {
e.preventDefault();
args.grid.navigateNext();
}
};
this.save = function () {
args.commitChanges();
};
this.cancel = function () {
$input.val(defaultValue);
args.cancelChanges();
};
this.hide = function () {
$wrapper.hide();
};
this.show = function () {
$wrapper.show();
};
this.position = function (position) {
};
this.destroy = function () {
$wrapper.remove();
};
this.focus = function () {
$input.focus();
};
this.loadValue = function (item) {
$input.val(defaultValue = item[args.column.field]);
$input.select();
};
this.serializeValue = function () {
return $input.val();
};
this.applyValue = function (item, state) {
item[args.column.field] = state;
};
this.isValueChanged = function () {
return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
};
this.validate = function () {
return {
valid: true,
msg: null
};
};
this.init();
}

Keeping the accordion menu open to show selected menu item

I have the following code for an accordion menu (see below).
How would I keep the current page menu item showing as at the moment whenever I move onto the page the menu closes down to only the top level?
I was also wondering if it's possible to have the accordion menu open up on click AND a page open at the same time??)
Thanks for any help anyone can give!
function initMenu() {
$(".sub-menu").hide();
$(".current_page_item .sub-menu").show();
$('#menu li a').click(
function() {
var checkElement = $(this).next();
if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
checkElement.slideUp('normal');
return false;
}
if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
$('#menu ul:visible').not(checkElement.parentsUntil('#menu')).slideUp('normal');
checkElement.slideDown('normal');
return false;
}
});
$('.current-menu-item').parentsUntil('#menu').slideDown('normal');
}
$(function() {
initMenu();
});
The initMenu() function, should look like this:
function initMenu() {
$(".sub-menu").hide();
$(".current_page_item .sub-menu").show();
$('#menu li a').click(
function() {
var checkElement = $(this).next();
if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
checkElement.slideUp('normal');
return false;
}
if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
$('#menu ul:visible').not(checkElement.parentsUntil('#menu')).slideUp('normal');
checkElement.slideDown('normal');
return false;
}
});
$('.current-menu-item').parentsUntil('#menu').slideDown('normal');
var FullCurrentURL = window.location.href;
var CurrentURLparts = FullCurrentURL.split("/");
var CurrentURLindex = CurrentURLparts.length - 1;
var CurrentURL = CurrentURLparts[CurrentURLindex];
$('#menu li a').each(function () {
var fullLinkURL = $(this).attr('href');
var LinkURLparts = fullLinkURL.split("/");
var LinkURLindex = LinkURLparts.length - 1;
var LinkURL = LinkURLparts[LinkURLindex];
if (LinkURL === CurrentURL){
$(this).parents("li").addClass("current-menu-item");
$(this).closest("ul").css('display', 'block');
}
});
}
$(function() {
initMenu();
});

alert() message isn't being called in my form

Firebug is giving me no error messages, but it's not working. The idea is regardless of whether the user picks an option from dropdown or if they type in something in search box, I want the alert() message defined below to alert what the value of the variable result is (e.g. {filter: Germany}). And it doesn't. I think the javascript breaks down right when a new Form instance is instantiated because I tried putting an alert in the Form variable and it was never triggered. Note that everything that pertains to this issue occurs when form.calculation() is called.
markup:
<fieldset>
<select name="filter" alter-data="dropFilter">
<option>Germany</option>
<option>Ukraine</option>
<option>Estonia</option>
</select>
<input type="text" alter-data="searchFilter" />
</fieldset>
javascript (below the body tag)
<script>
(function($){
var listview = $('#listview');
var lists = (function(){
var criteria = {
dropFilter: {
insert: function(value){
if(value)
return handleFilter("filter", value);
},
msg: "Filtering..."
},
searchFilter: {
insert: function(value){
if(value)
return handleFilter("search", value);
},
msg: "Searching..."
}
}
var handleFilter = function(key,value){
return {key: value};
}
return {
create: function(component){
var component = component.href.substring(component.href.lastIndexOf('#') + 1);
return component;
},
setDefaults: function(component){
var parameter = {};
switch(component){
case "sites":
parameter = {
'order': 'site_num',
'per_page': '20',
'url': 'sites'
}
}
return parameter;
},
getCriteria: function(criterion){
return criteria[criterion];
},
addCriteria: function(criterion, method){
criteria[criterion] = method;
}
}
})();
var Form = function(form){
var fields = [];
$(form[0].elements).each(function(){
var field = $(this);
if(typeof field.attr('alter-data') !== 'undefined') fields.push(new Field(field));
})
}
Form.prototype = {
initiate: function(){
for(field in this.fields){
this.fields[field].calculate();
}
},
isCalculable: function(){
for(field in this.fields){
if(!this.fields[field].alterData){
return false;
}
}
return true;
}
}
var Field = function(field){
this.field = field;
this.alterData = false;
this.attach("change");
this.attach("keyup");
}
Field.prototype = {
attach: function(event){
var obj = this;
if(event == "change"){
obj.field.bind("change", function(){
return obj.calculate();
})
}
if(event == "keyup"){
obj.field.bind("keyup", function(e){
return obj.calculate();
})
}
},
calculate: function(){
var obj = this,
field = obj.field,
msgClass = "msgClass",
msgList = $(document.createElement("ul")).addClass("msgClass"),
types = field.attr("alter-data").split(" "),
container = field.parent(),
messages = [];
field.next(".msgClass").remove();
for(var type in types){
var criterion = lists.getCriteria(types[type]);
if(field.val()){
var result = criterion.insert(field.val());
container.addClass("waitingMsg");
messages.push(criterion.msg);
obj.alterData = true;
alert(result);
initializeTable(result);
}
else {
return false;
obj.alterData = false;
}
}
if(messages.length){
for(msg in messages){
msgList.append("<li>" + messages[msg] + "</li");
}
}
else{
msgList.remove();
}
}
}
$('#dashboard a').click(function(){
var currentComponent = lists.create(this);
var custom = lists.setDefaults(currentComponent);
initializeTable(custom);
});
var initializeTable = function(custom){
var defaults = {};
var custom = custom || {};
var query_string = $.extend(defaults, custom);
var params = [];
$.each(query_string, function(key,value){
params += key + ': ' + value;
})
var url = custom['url'];
$.ajax({
type: 'GET',
url: '/' + url,
data: params,
dataType: 'html',
error: function(){},
beforeSend: function(){},
complete: function() {},
success: function(response) {
listview.html(response);
}
})
}
$.extend($.fn, {
calculation: function(){
var formReady = new Form($(this));
if(formReady.isCalculable) {
formReady.initiate();
}
}
})
var form = $('fieldset');
form.calculation();
})(jQuery)
Thank you for anyone who responds. I spent a lot of time trying to make this work.
The initial problem as to why the alert() was not being triggered when Form is instantiated is because, as you can see, the elements property belongs to the Form object, not fieldset object. And as you can see in the html, I place the fields as descendents of the fieldset object, not form.