How we can implement the Onclick functionality in titanium grid view item - javascript

I have developed the gridview application using the widget (from this code)
https://github.com/pablorr18/TiDynamicGrid
i have modified the code as per my client requirements. Now if i like to click the view cart button on the list item it will alert the message like "Am clicked". But i tried in various ways.but i can't find the solutions. Can anyone please explain me how we are write the code for this.
I have follows below code in my application:
var items = [];
var showGridItemInfo = function(e){
alert("Onclick the row");
};
var delay = (OS_ANDROID) ? 1000:500;
$.tdg.init({
columns:3,
space:5,
delayTime:delay,
gridBackgroundColor:'#e1e1e1',
itemBackgroundColor:'#fff',
itemBorderColor:'transparent',
itemBorderWidth:0,
itemBorderRadius:5,
onItemClick: showGridItemInfo
});
function createSampleData(){
var sendit = Ti.Network.createHTTPClient({
onerror: function(e){
Ti.API.debug(e.error);
alert('There was an error during the connection');
},
timeout:10000,
});
sendit.open('GET', url+'android_livedev/client/test.php?action=listitems&categoryid='+subcategorylist_category_id+'&productmin=0&productmax=50');
sendit.send();
sendit.onload = function(){
var response = JSON.parse(this.responseText);
if(response[0].success == 0){
alert("No Products Found");
}
else {
items = [];
for (var x=0;x<response[0].data.length;x++){
var view = Alloy.createController('item_layout',{
image:imageurl+response[0].data[x].thumb_image,
product:response[0].data[x].product,
productprice:"$"+" "+response[0].data[x].price,
onItemClick: addcart,
}).getView();
var values = {
product: response[0].data[x].product,
image: response[0].data[x].thumb_image,
productid : response[0].data[x].productid,
};
items.push({
view: view,
data: values
});
};
$.tdg.addGridItems(items);
reateSampleData();
$.tdg.clearGrid();
$.tdg.init({
columns:nColumn,
space:nSpace,
delayTime:delay,
gridBackgroundColor:'#e1e1e1',
itemHeightDelta: 0,
itemBackgroundColor:'#fff',
itemBorderColor:'transparent',
itemBorderWidth:0,
itemBorderRadius:5,
onItemClick: showGridItemInfo
});
createSampleData();
});
$.win.open();
The item_layout.xml code is looking like :
<Alloy>
<View id="mainView">
<ImageView id="thumb"/>
<Label id="product"></Label>
<Label id="productprice"></Label>
<Button id="addcart" onClick="additemtocart"/>
</View>
</Alloy>
EDIT:
now am getting the view and the button id from that specified view. But if am trying to click the button means can't able to do. can you check my code and give a solution.
i have added the below code :
var view = Alloy.createController('item_layout',{
image:imageurl+response[0].data[x].thumb_image,
product:response[0].data[x].product,
productprice:"$"+" "+response[0].data[x].price
}).getView();
var controller = Alloy.createController('item_layout');
var button = controller.getView('addcart');
button.addEventListener('click', function (e){
alert("click");
Ti.API.info('click');
});

First switch the ids to classes because they're non-unique. Only use ID's if you must. Second, try something like this:
Try something like this:
$('.addCart').click(function() {
var item = $(this).silblings('.product').text;
addItemToCart(item);
});
Even better, add a data-productId attribute to the shopping cart button and you could do something like this:
$('.addCart').click(function() {
var itemId = $(this).attr('data-productId');
addItemToCart(itemId);
});
This is better since you're only requiring the shopping cart button to be on the screen.
All this said, you also probably need to include a fallback that adds the item to the cart when javascript isn't available on the page.

Related

CSHTML button with javascript onlick function only works some times?

I have a download button set up on a web page that is iteratively assigned an ID based on the how many questions are posted.
Here is the button:
<input data-bind="attr: { id: $index() }" type="button" value="Download" class="download" />
Here is the the JS function that finds the number assigned and does the onclick:
#Scripts.Render("~/bundles/knockout")
<script type="text/javascript">
var SDNo = 0;
$(document).ready(function () {
SystemJS.import('sd/questions').then(function (modules) {
//Code here for another section that fills out the questions not relevant apart from assigning SDNo
});
SystemJS.import('sd/download').then(function (modules2) {
var attachVM = new modules2.Attachment();
//$("#download").click(function () {
$("input[class^='download'], input[class*=' download']").each(function () {
$(this).click(function () {
var id = $(this).attr('id');
let passedValue = id.concat("-" + SDNo);
attachVM.download(passedValue);
});
});
});
The above function allows me to go off to a typescript file and handle the required API call to GET a file
that code is here:
typescript
export class Attachment {
async download(ID: Number) {
window.open(await WebApi.getJSON('SD', 'Download', Number));
}
}
So yeah it'll work then it'll randomly stop working for no reason that I can find and obviously no errors thrown, via debugging it doesn't even get into the typescript file at all nothing happens. But then sometimes it goes all the way through into the controller doing what it needs to do.
As per #LouysPatriceBessette
$("input[class^='download'], input[class*=' download']").each(function () {
$(this).click(function () {
var id = $(this).attr('id');
let passedValue = id.concat("-" + SDNo);
attachVM.download(passedValue);
});
to
$("input.download").on("click", function() {
var id = $(this).attr('id');
let passedValue = id.concat("-" + SDNo);
attachVM.download(passedValue);
});
And it works consistently now thank you again.

How to prevent rebind on kendo grid data item change?

I have a kendo grid, and when an item is selected I want to modify the underlying dataitem so i'm doing this ...
selectionChange: function(e)
{
var component = $(this.table).closest('.component');
var grid = this;
var val = !component.hasClass("secondary");
var selection = grid.dataItems(grid.select());
selection.forEach(function () {
this.set("SaleSelected", val);
});
}
I also have 2 buttons that allow me to push items between the 2 grids which do this ...
select: function (e) {
e.preventDefault();
var sender = this;
// get kendo data source for the primary grid
var source = $(sender).closest(".component")
.find(".component.primary")
.find(".details > [data-role=grid]")
.data("kendoGrid")
.dataSource;
// sync and reload the primary grid
source.sync()
.done(function () {
source.read();
my.Invoice.reloadGridData($(sender).closest(".component").find(".component.secondary").find(".details > [data-role=grid]"));
});
return false;
},
deselect: function (e) {
e.preventDefault();
var sender = this;
debugger;
// get kendo data source for the secondary grid
var source = $(sender).closest(".component")
.find(".component.secondary")
.find(".details > [data-role=grid]")
.data("kendoGrid")
.dataSource;
// sync and reload the primary grid
source.sync()
.done(function () {
source.read();
my.Invoice.reloadGridData($(sender).closest(".component").find(".component.primary").find(".details > [data-role=grid]"));
});
return false;
}
Essentially the "selected items" from grid1 can be marked as such on the server then the grids get reloaded to move the items over.
All good I thought, but apparently Kendo has other ideas.
Editing a data item causes its owning grid to rebind losing the selection state resulting in some confusing behaviour for the user.
Is there a way to tell kendo "i'm going to edit this unbound property right now, don't go messing with binding"?
Ok it turns out kendo is a bit of a wierdo and I still have no idea why they insist you call all their "api stuff" to do simple tasks when doing things more directly actually works better.
In my case I removed the selection change call altogether and let kendo handle that, then in my selection button handlers to move the data between grids I updated the properties directly on the data items instead of calling
"item.set("prop", value)" i now have to do "item.prop = value".
The net result is this ...
select: function (e) {
e.preventDefault();
var sender = this;
// get some useful bits
var component = $(sender).closest(".component");
var primaryGrid = component.find(".component.primary").find(".details > [data-role=grid]").data("kendoGrid");
// get the new selection, and mark the items with val
var selection = $(primaryGrid.tbody).find('tr.k-state-selected');
selection.each(function (i, row) {
primaryGrid.dataItem(row).SaleSelected = true;
primaryGrid.dataItem(row).dirty = true;
});
// sync and reload the primary grid
primaryGrid.dataSource.sync()
.done(function () {
primaryGrid.dataSource.read();
component.find(".component.secondary")
.find(".details > [data-role=grid]")
.data("kendoGrid")
.dataSource
.read();
});
return false;
},
deselect: function (e) {
e.preventDefault();
var sender = this;
// get some useful bits
var component = $(sender).closest(".component");
var secondaryGrid = component.find(".component.secondary").find(".details > [data-role=grid]").data("kendoGrid");
// get the new selection, and mark the items with val
var selection = $(secondaryGrid.tbody).find('tr.k-state-selected');
selection.each(function (i, row) {
secondaryGrid.dataItem(row).SaleSelected = false;
secondaryGrid.dataItem(row).dirty = true;
});
// sync and reload the primary grid
secondaryGrid.dataSource.sync()
.done(function () {
secondaryGrid.dataSource.read();
component.find(".component.primary")
.find(".details > [data-role=grid]")
.data("kendoGrid")
.dataSource
.read();
});
return false;
}
kendo appears to be taking any call to item.set(p, v) as a trigger to reload data so avoiding the kendo wrapper and going directly to the item properties allows me direct control of the process.
Moving the code from the selection change event handler to the button click handler also means i only care about that data being right when it actually needs to be sent to the server, something I just need to be aware of.
I don't like this, but it's reasonably clean and the ui shows the right picture even if the underlying data isn't quite right.
My other option would be to create a custom binding but given that the binding would have to result in different results depending on weather it was binding to the primary or the secondary grid I suspect that would be a lot of js code, this feels like the lesser of 2 evils.
I think you can bind the dataBinding event to just a "preventDefault" and then unbind it and refresh at your leisure
var g = $("#myGrid").data("kendoGrid");
g.bind("dataBinding", function(e) { e.preventDefault(); });
then later...
g.unbind("dataBinding");

Prevent multiple ajax submissions on multiple clicks

I've a WordPress blog running this jQuery code that allows users to click a bookmark link that saves the post as a bookmark. Each post shows a total bookmark counter that looks like: "Bookmarked (5)". Although this code works, it registers multiple clicks whenever someone clicks multiple times on the bookmark link and then saves the same post as multiple bookmarks. When the user tries to remove the bookmark by clicking on the bookmark link again, it registers multiple clicks again and the counter starts showing minus numbers which looks like: "Bookmarked (-5)".
I've been searching for an instruction on how to prevent this from happening so that the bookmark counter never runs minus and the user can't bookmark the same post multiple times but had no success so far.
Here is the jQuery code that I'm using:
jQuery(document).ready( function($) {
var added_message = upb_vars.added_message;
var delete_message = upb_vars.delete_message
$(document).on('click', '.upb_add_bookmark', function () {
var post_id = $(this).attr('rel');
var data = {
action: 'bookmark_post',
post_read: post_id
};
$.post(upb_vars.ajaxurl, data, function(response) {
$('.upb_bookmark_control_'+post_id).toggle();
if($('.upb-bookmarks-list').length > 0 ) {
var bookmark_data = {
action: 'insert_bookmark',
post_id: post_id
};
$.post(upb_vars.ajaxurl, bookmark_data, function(bookmark) {
$(bookmark).appendTo('.upb-bookmarks-list');
$('.no-bookmarks').fadeOut();
});
}
});
return false;
});
$(document).on('click', '.upb_del_bookmark', function () {
var post_id = $(this).attr('rel');
var data = {
action: 'del_bookmark',
del_post_id: post_id
};
$.post(upb_vars.ajaxurl, data, function(response) {
$('.bookmark-'+post_id).fadeOut();
$('.upb_bookmark_control_'+post_id).toggle();
});
return false;
});
});
Could you please help me solve this problem?
Thanks a lot!
One way is to add a .disabled class to your link before the $.post().
// Before ajax...
if ($(this).hasClass('disabled')) {
return false;
} else {
$(this).addClass('disabled');
}
// Make sure we refer to the same element
var that = this;
// On post success...
$(that).removeClass('disabled');

Implementing Amazon Wishlist Like Undo in AngularJS

I'm thinking of implementing an "Amazon Wishlist-ish" undo functionality to my app.
I mean...
then click 'Delete Item'
by clicking 'Undo', the deletion appears to be canceled
My list controller is currently looking like this,
function ListsController($scope, List) {↲
List.get({}, function(lists) {
$scope.lists = lists.objects;
$scope.delete_list = function(index) {
var isConfirmed = confirm('Are you sure you want to delete it?');
if (isConfirmed) {
var targetlist = $scope.lists[index];
List.delete({ listId: targetlist.id },
function(list) {
$scope.lists.splice(index, 1);
}
)
}
}
});
};
But I wanna enable undo feature as I said.
What is the best way to do that in angular js?
I can't give an exact example without seeing what the List service does, but I think your best bet is to keep track of removed items in another scope variable and if the undo is clicked you just add it back to lists.
Maybe something like:
$scope.deleted_lists = [];
$scope.delete_list = function(index) {
var isConfirmed = confirm('Are you sure you want to delete it?');
if (isConfirmed) {
var targetlist = $scope.lists[index];
List.delete({ listId: targetlist.id }, function(list) {
$scope.deleted_lists.concat($scope.lists.splice(index, 1));
});
}
};
Then you can use an ng-repeat (if you want multiple undos) to display the deleted items and a click on the undo button could simply add the item back to the list via .push().

How to propertly select items which are still loaded using promises?

I have list of item IDs on page load:
var itemIds = [1, 5, 10, 11];
IDs are rendered into list and shown to user. I have function which loads detailed information about item, it returns Promise/A.
function loadInfo(id) { ... }
Loading of info for all items is initiated on page load:
val infos = {};
$.each(itemIds, function(i, id) { infos[id] = loadInfo(id); }
Now the problem itself.
When user clicks on item ID:
if item info is loaded, info must be shown
if item info is not yet loaded, it must be shown when it is loaded
Looks easy:
$('li').click(function() {
var id = $(this).data('item-id');
infos[id].then(function(info) { $('#info').text(info); });
});
But if user cliked on another item before current one is loaded, then I have to cancel handler on current item promise and schedule on new one.
How to properly do it?
I have several working solutions (like maintaining currentItemId variable and checking it in promise handler), but they are ugly. Should I look to reactive programming libraries instead?
Kriomant,
I guess there's a number of ways you could code this. Here's one :
var INFOS = (function(){
var infoCache = {},
promises = {},
fetching = null;
var load = function(id) {
if(!promises[id]) {
promises[id] = $ajax({
//ajax options here
}).done(function(info){
infoCache[id] = info;
delete promises[id];
});
}
return promises[id];
}
var display = function(id, $container) {
if(fetching) {
//cancel display (but not loading) of anything latent.
fetching.reject();
}
if(infoCache[id]) {
//info is already cached, so simply display it.
$container.text(infoCache[id]);
}
else {
fetching = $.Deferred().done(function() {
$container.text(infoCache[id]);
});
load(id).done(fetching.resolve);
}
}
return {
load: load,
display: display
};
})();
As you will see, all the complexity is bundled in the namespace INFOS, which exposes two methods; load and display.
Here's how to call the methods :
$(function() {
itemIds = ["p7", "p8", "p9"];
//preload
$.each(itemIds, function(i, id) { INFOS.load(id); });
//load into cache on first click, then display from cache.
$('li').on('click', function() {
var id = $(this).data('item-id');
INFOS.display(id, $('#info'));
});
});
DEMO (with simulated ajax)
The tricks here are :
to cache the infos, indexed by id
to cache active jqXHR promises, indexed by id
to display info from cache if previously loaded ...
... otherwise, each time info is requested, create a Deferred associated with display of the info, that can be resolved/rejected independently of the corresponding jqXHR.

Categories

Resources