Mobile list item pressed and longtap event - mobile

In this little qooxdo mobile example I need know the list item pressed when longtap is triggered. How I can know?
var page = new qx.ui.mobile.page.NavigationPage();
page.setTitle("List");
page.addListener("initialize", function() {
var list = new qx.ui.mobile.list.List({
configureItem : function(item, data, row) {
item.setTitle(data.title);
item.setSubtitle(data.subTitle);
item.setSelectable(true);
item.setShowArrow(true);
}
});
var data = [];
for (var i=0; i < 50; i++) {
data.push({title:"Item" + i, subTitle:"Subtitle for Item #" + i});
}
list.setModel(new qx.data.Array(data));
list.addListener("changeSelection", function(evt) {
alert("Item Selected #" + evt.getData());
}, this);
list.addListener("longtap", function(evt) {
// <--- HERE I NEED KNOW THE LIST ITEM PRESSED
}, this);
page.getContent().add(list);
},this);
this.getManager().addDetail(page);
page.show();
please I need some help. Thanks

a solution:
list.addListener("longtap", function(evt) {
var originalTarget = evt.getOriginalTarget();
while (originalTarget.tagName != "LI") {
originalTarget = originalTarget.parentNode;
}
var itemIndex = parseInt(originalTarget.getAttribute("data-row"), 10);
alert("Item Selected #" + itemIndex);
});

Related

Isotope: Combined multiple checkbox and searchbox filtering

I'm trying to combine the Isotope multiple checkbox filtering with a searchbox.
I used the example with the checkbox filters from here and tried to implement the searchbox but with no luck.
Just the checkbox filtering works well. I think i'm close to the solution but my javascript skills are at a very beginner level.
I commented out the section of what i've tried to implement.
Thank you for some hints
// quick search regex
var qsRegex;
var $grid;
var filters = {};
var $grid = $('.grid');
//set initial options
$grid.isotope({
layoutMode: 'fitRows'
});
$(function() {
$grid = $('#grid');
$grid.isotope();
// do stuff when checkbox change
$('#options').on('change', function(jQEvent) {
var $checkbox = $(jQEvent.target);
manageCheckbox($checkbox);
var comboFilter = getComboFilter(filters);
/*var searchResult = qsRegex ? $(this).text().match(qsRegex) : true;
var filterResult = function() {
return comboFilter && searchResult;
}*/
$grid.isotope({
filter: comboFilter //or filterResult
});
});
});
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;
}
// use value of search field to filter
var $quicksearch = $('.quicksearch').keyup(debounce(function() {
qsRegex = new RegExp($quicksearch.val(), 'gi');
$grid.isotope();
}, ));
// debounce so filtering doesn't happen every millisecond
function debounce(fn, threshold) {
var timeout;
threshold = threshold || 100;
return function debounced() {
clearTimeout(timeout);
var args = arguments;
var _this = this;
function delayed() {
fn.apply(_this, args);
}
timeout = setTimeout(delayed, threshold);
}
}
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).prop('checked', false);
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.parents('.option-set').find(selector).prop('checked', false);
}
}
I found the solution by myself, but i had to add a second function for returning the searchresult. Otherwise the search function is triggered only after using a checkbox or leaving the search box input field.
How could i avoid this redundand code?
JS:
// use value of search field to filter
var $quicksearch = $('.quicksearch').keyup(debounce(function() {
qsRegex = new RegExp($quicksearch.val(), 'gi');
$grid.isotope();
}, 200));
$(function() {
$grid = $('#grid');
$grid.isotope({
filter: function() {
var searchResult = qsRegex ? $(this).text().match(qsRegex) : true;
return searchResult;
}
});
// do stuff when checkbox change
$('#options').on('change', function(jQEvent) {
var $checkbox = $(jQEvent.target);
manageCheckbox($checkbox);
var comboFilter = getComboFilter(filters);
$grid.isotope({
filter: function() {
var buttonResult = comboFilter ? $(this).is(comboFilter) : true;
var searchResult = qsRegex ? $(this).text().match(qsRegex) : true;
return buttonResult && searchResult;
}
});
});
});

Resizable handles duplicate problem in undo redo functionality

" I am using resizable handles directive.I am creating undo / redo functionality then i am push html into array, When ever i am click on the undo button resizable Handles becoming duplicate."
I am pushing inside ng-repeat html into array where i am using resizable directive.
When ever i am going to append html(array for undo/redo) resizable handles become duplicate.
app.directive('rotateimage', function($compile) {
return {
restrict: 'A',
link: function postLink(scope, elem, attrs) {
elem.resizable({
handles: "ne, nw, se, sw,n,e,s,w",
aspectRatio: true
});
elem.on('resizestop', function(evt, ui) {
scope.id = [];
scope.style = [];
scope.html = [];
var id = elem.parent(".div01").attr('id');
scope.id.push(id);
scope.style.push($("#" + id).attr('style'));
$("#" + id).find(".ui-resizable-handle").remove();
scope.html.push($("#" + id).html().trim());
scope.historyApp.add(scope.style, scope.id, scope.html);
});
elem.on('resizestart', function(evt, ui) {
console.log("loll");
scope.id = [];
scope.style = [];
scope.html = [];
var id = elem.parent(".div01").attr('id');
scope.id.push(id);
scope.style.push($("#" + id).attr('style'));
$("#" + id).find(".ui-resizable-handle").remove();
scope.html.push($("#" + id).html().trim());
scope.historyApp.add(scope.style, scope.id, scope.html);
});
}
};
});
$scope.historyApp = {
stackStyle: [],
stackId: [],
html: [],
dataorignlbgcrop: [],
databbgval: [],
counter: -1,
add: function(style, id, html) {
++this.counter;
this.stackStyle[this.counter] = style;
this.stackId[this.counter] = id;
this.html[this.counter] = html;
this.doSomethingWith(style, id, html);
$scope.countBoxVal = true;
// delete anything forward of the counter
this.stackStyle.splice(this.counter + 1);
$scope.countBoxVal = true;
//alert(this.counter);
// alert($scope.countBoxVal);
},
undo: function() {
--this.counter;
// this.doSomethingWith(this.stackStyle[this.counter],this.stackId[this.counter]);
this.doSomethingWith(this.stackStyle[this.counter], this.stackId[this.counter], this.html[this.counter]);
--this.counter;
$scope.countBoxVal = false;
},
redo: function() {
++this.counter;
++this.counter;
this.doSomethingWith(this.stackStyle[this.counter], this.stackId[this.counter], this.html[this.counter]);
},
doSomethingWith: function(style, id, html) {
if (this.counter <= 0) {
this.counter = 0;
$scope.couterStackEnter = "enter";
//$scope.couterStackExit="undefined";
$('#undo').addClass('disabled');
$('#redo').removeClass('disabled');
} else {
$('#undo').removeClass('disabled');
}
var mathPro = Math.abs(this.counter);
var kp = mathPro + 1;
if (Math.abs(this.counter) >= this.stackStyle.length) {
$('#redo').addClass('disabled');
$scope.couterStackExit = "exit";
} else {
$('#redo').removeClass('disabled');
}
angular.forEach(html, function(val, key) {
console.log($scope.historyApp);
var myEl = angular.element(document.querySelector('#' + id[key]));
var ids = myEl.find(".forReverseUndoRedo").attr("id");
var myEls = angular.element(document.querySelector('#' + ids));
setTimeout(function() {
myEl.attr("style", style);
// myEls.clone().html("");
myEl.html("");
myEl.find(".ui-resizable-handle").remove();
myEl.append($compile(val)($scope));
$scope.$digest();
}, 100);
});
}
};

Can't $update or $set ~ "undefined is not a function" ~ AngularFire

What I'm trying to do:
Update the status to "TAKEN" when the chat is closed.
Issue:
Can't get $scope.currentChat.$set() or $scope.currentChat.$update() to work when trying to update the status. (See the $scope.close() function.)
What I've tried:
Various methods including $set, $update; I don't know. A lot of things. Been researching this for several hours, and can't find a solution that works.
NOTES:
$scope.currentChat.$set({status:"TAKEN"}); Doesn't work.
$scope.currentChat.$getRecord('status'); Works. Returns:
Object {$value: "OPEN", $id: "status", $priority: null}
So what exactly is going on here? Why can't I seem to set the status to TAKEN?
The issue is currently in the $scope.close() function, when trying to update the status:
// $SCOPE.CLOSE
// - Closes the current ticket.
$scope.close = function() {
// $scope.ticketObject.status = "TAKEN";
// $scope.currentChat.$set({status:"TAKEN"});
console.log("===========================");
console.log("STATUS:");
console.log($scope.currentChat.$getRecord('status'));
console.log($scope.currentChat['status']);
console.log("===========================");
$scope.ticketObject = {};
$scope.ticket = false;
$scope.toggle();
}
Here's my code:
bloop.controller('HomeCtrl', ['$scope', '$firebase', function($scope, $firebase) {
console.log("HomeController!");
var url = 'https://**********.firebaseio.com/tickets/';
var ref = new Firebase(url);
// $SCOPE.CREATETICKET
// - This function makes a connection to Firebase and creates the ticket.
$scope.createTicket = function() {
$scope.tickets = $firebase(ref).$asArray();
$scope.tickets.$add($scope.ticketObject).then(function(r) {
var id = r.name();
$scope.currentFBID = id;
$scope.syncTickets();
console.log("===========================");
console.log("CREATED TICKET: " + $scope.currentFBID);
console.log("URL: " + url + $scope.currentFBID);
console.log("===========================");
});
}
// $SCOPE.SYNCTICKETS
// - This function makes a connection to Firebase and syncs the ticket with the $scope to easily update the tickets.
$scope.syncTickets = function() {
var ticketRefURL = new Firebase(url + $scope.currentFBID);
$scope.currentChat = $firebase(ticketRefURL).$asArray();
$scope.currentChat.$save($scope.ticketObject);
var archiveRefURL = new Firebase(url + $scope.currentFBID + "/archive");
$scope.currentChat.archive = $firebase(archiveRefURL).$asArray();
console.log("===========================");
console.log("SAVED TICKET: " + $scope.currentFBID);
console.log("URL: " + ticketRefURL);
console.log("ARCHIVE URL: " + archiveRefURL);
console.log("===========================");
}
// $SCOPE.POST
// - This function pushes whatever is typed into the chat into the chat archive.
// - $scope.ticketObject.archive (is an array of objects)
$scope.post = function(name) {
// Push to ticketObject.archive array...
$scope.ticketObject.archive.push({
"name" : name,
"text" : $scope.chatText
});
// Logging the array to make sure it exists...
console.log("===========================");
console.log("CHAT ARCHIVE:");
console.log($scope.ticketObject.archive);
console.log("===========================");
$scope.currentChat.archive.$add({
"name" : name,
"text" : $scope.chatText
});
// This resets the text area so it's empty...
$scope.chatText = "";
} // WORKS
// $SCOPE.CLOSE
// - Closes the current ticket.
$scope.close = function() {
// $scope.ticketObject.status = "TAKEN";
// $scope.currentChat.$set({status:"TAKEN"});
console.log("===========================");
console.log("STATUS:");
console.log($scope.currentChat.$getRecord('status'));
console.log($scope.currentChat['status']);
console.log("===========================");
$scope.ticketObject = {};
$scope.ticket = false;
$scope.toggle();
}
// $SCOPE.TOGGLE
// - This function toggles the chat to be either open or closed.
$scope.toggle = function() {
if($scope.toggleState === false) {
$scope.toggleState = true;
$scope.checkTicket();
} else if($scope.toggleState === true) {
$scope.toggleState = false;
}
}
// $SCOPE.CHECKTICKET
// - This function checks to see if there's an existing ticket.
// - If there's not an existing ticket, it creates one.
$scope.checkTicket = function() {
if($scope.ticket === false) {
// Generate New Ticket Data
$scope.ticketObject = newTicket();
// Create the Ticket
$scope.createTicket();
// Ticket now exists.
$scope.ticket = true;
}
}
function newTicket() {
var ticketID = generateTicketID();
var newTicket = {
id: ticketID,
status: "OPEN",
name: "N/A",
email: "N/A",
date: generateDate(),
opID: "Unassigned",
opName: "Unassigned",
archive: [],
notes: []
}
return newTicket;
}
function generateTicketID() {
var chars = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
var result = '';
for(var i=12; i>0; --i) {
result += chars[Math.round(Math.random() * (chars.length - 1))];
}
return result;
}
function generateDate() {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1;
var yyyy = today.getFullYear();
if(dd < 10) {
dd = '0' + dd;
}
if(mm < 10) {
dd = '0' + mm;
}
var date = mm + "/" + dd + "/" + yyyy;
return date;
}
}]);
$update and $set are part of the $firebase API. You are attempting to call them on the synchronized array returned by $asArray(), which is a $FirebaseArray instance. That has its own API, which includes neither update nor set.

CheckBox in ComboBox

I would like to have checkBoxes inside a comboBox, like in this simplified example :
var rawData = [];
for (var i = 0; i < 20; i++) {
rawData.push(i);;
}
var data = new qx.data.Array(rawData);
var list = new qx.ui.form.ComboBox();
list.setWidth(150);
this.getRoot().add(list);
var controller = new qx.data.controller.List(null, list);
var delegate = {
createItem : function() {
return new qx.ui.form.CheckBox();
}
};
controller.setDelegate(delegate);
controller.setModel(data);
It's working but i'm not able to "check" the checkboxes because the combobox is closed when i click on it, so i would like to open/close the combobox only with the button.
How to do it? Thanks in advance.
Some event of the ComboBox is responsible for closing the PopUp (see code on GitHub) before the click can get to an underlying checkbox. If you implement your own ComboBox and overwrite the close method it works.
qx.Class.define("foo.ComboBox", {
extend: qx.ui.form.ComboBox,
members: {
close: function() {
}
}
})
var rawData = [];
for (var i = 0; i < 20; i++) {
rawData.push(i);;
}
var data = new qx.data.Array(rawData);
var list = new foo.ComboBox();
list.setWidth(150);
var controller = new qx.data.controller.List(null, list);
var delegate = {
createItem : function() {
return new qx.ui.form.CheckBox();
}
};
controller.setDelegate(delegate);
controller.setModel(data);
this.getRoot().add(list);
However now you have to think about how you will handle multiple selection of checkboxes and when to close the popup.

Delete multiple items from grid using CheckboxSelectionModel

Using ExtJs4.1 on Sencha Architect.
I have following code in my onDeleteButton code
onDeleteButtonClick: function(button, e, options) {
var active = this.activeRecord;
var myGrid = Ext.getCmp('publisherResultsGridView'),
sm = myGrid.getSelectionModel(),
selection = sm.getSelection(); // gives you a array of records(models)
if (selection.length > 0){
for( var i = 0; i < selection.length; i++) {
this.application.log('OnDeleteItemID is ' + selection);
}
this.remove(selection);
}
Code for Remove Function
remove: function(record) {
var store = Ext.getStore('PublisherProperties');
store.proxy.url = MasterDataManager.globals.url + "Publishers/";
store.remove(record);
store.sync();
When I run it, I could see an array of objects in my log, also I dont get any errors after the remove function is executed. But the store doesnt update, I mean it doesnt remove the selected items.
Can somebody please help me.
Thanks
I solved my problem by making the following changes.
To onDeleteButtonClick
if (selection.length > 0){
for( var i = 0; i < selection.length; i++) {
this.application.log('OnDeleteItemID is ' + selection[i].data.id);
this.remove(selection[i]);
}
}
To Remove function
remove: function(record) {
var store = Ext.getStore('PublisherProperties');
this.application.log('Remove Function is ' + record);
store.proxy.url = MasterDataManager.globals.url + "Publishers/" + record.data.id;
store.load({
scope : this,
callback : function(records, operation, success){
if (records.length > 0){
var store2 = Ext.getStore('PublisherProperties');
store2.proxy.url = MasterDataManager.globals.url + "Publishers/";
store2.remove(records[0]);
store2.sync();
}
}
});
//store.remove(record);
//store.sync();

Resources