If condition in Kendo UI grid template - kendo-ui

field: 'Status' ,
width: '70px' ,
template: "#if(Status == 'On Request') {#<div class='redAndBold'>#:Status</div>#}#"
I have a kendo UI grid where the "Status" is being filled in from the javascript file. The Status in the model can be "On Request", and what I want is: if it is "On Request", add a class to it, "redAndBold". The syntax in this particular example gives a "user is not defined" error.
Could anyone give me some pointers on how to correctly do this?

The kendo.templates depend on #=fieldName# or #:fieldName#. In the current case, there is a missing closing "#" after 'Status'. The templates are evaluated with the value of the field when bound to a data item during initialization. For executing JavaScript logic use only "#JS logic goes here#". Further information can be found here Kendo UI templates.
To avoid confusion of the template syntax, plain JavaScript function can be used instead:
template: "#=templateFunc(data)#"
// JS hander
function templateFunc(dataItem){
if(dataItem.Status== 'On Request') {
return "<div class='redAndBold'>"+dataItem.Status+"</div>";
} else{
return dataItem.Status;
}
}

I think you are missing a # after Status. When you inject the value of a variable it needs a # before and after. If you split the template code over several lines whilst you write it, it can be easier to get it right.
#if(Status == 'On Request') {#
<div class='redAndBold'>
#:Status#
</div>
#}#
A good check is to count the number of # symbols in your template. It should always be an even number.

As many people pointed out, you're missing a pound sign. I would like to point out that you can set the template as a function that returns a string. I generally do this because there are nuances with the string template such as escaping pound signs among other things:
field: 'Status',
width: '70px',
template: function(dataItem) {
var div = $('<div />');
if (dataItem.Status === 'On Request') {
div.addClass('redAndBold');
}
return div.prop('outerHTML');
}

Just use function for a template :
}, {
field: "TrackingNumber",
title: "#T("Admin.Orders.Shipments.TrackingNumber")",
}, {
field: "ShippingMethodName",
title: "#T("Admin.Orders.Shipments.ShippingMethodName")",
template:function(dataItem) {
var template;
var ShippingMethodPluginName = dataItem.ShippingMethodPluginName;
var IsReferanceActive = dataItem.IsReferanceActive;
var ShippingMethodName = dataItem.ShippingMethodName;
var CargoReferanceNo = dataItem.CargoReferanceNo;
var ShipmentStatusId = dataItem.ShipmentStatusId;
if (ShipmentStatusId == 7) {
return "<div align='center'><label class='label-control'><b style='color:red'>Sipariş İptal Edildi<b></label></div>";
} else {
if (ShippingMethodPluginName == "Shipping.ArasCargo" || ShippingMethodPluginName == "Shipping.ArasCargoMP") {
template =
"<div align='center'><img src = '/content/images/aras-kargo-logo.png' width = '80' height = '40'/> <label class='label-control'><b>Delopi Aras Kargo Kodu<b></label>";
if (IsReferanceActive) {
template =
template +
"<label class='label-control'><b style='color:red; font-size:20px'>"+CargoReferanceNo+"<b></label></div>";
}
return template;
}

Related

Shopify: How can I render the recommended products?

I am trying to use Shopify Ajax API to get recommended products inside the cart. I am able to get the recommended product's json but not the section rendering.
The script (note section_id):
jQuery.getJSON('/cart.js', function(cart) {
// first recommendation
jQuery.getJSON("/recommendations/products.json?product_id=" + cart.items[0].product_id + "&limit=6&section_id=recommended_first", function(
response
) {
var recommendedProducts = response.products;
}
});
})
The HTML:
<div id="recommended_first" class="upsell_product">
</div>
I get some messages in the console:
Error: ShopifyAnalytics.meta.page.pageType is empty: undefined
Fallback logic initiated
What am I missing? I didn't find any examples in the Shopify doc.
Thanks a lot!
Your code will not work because you have an extra } on line 7. Assuming the cart request returns valid data, the following code should work (also a good idea to check if the cart request returns any items before using the cart.items variable):
jQuery.getJSON('/cart.js', function(cart) {
jQuery.getJSON("/recommendations/products.json?product_id=" + cart?.items?[0]?.product_id + "&limit=6&section_id=recommended_first", function(response) {
var recommendedProducts = response.products;
var recommendedProductsHTML = "";
for (i = 0; i < recommendedProducts.length; i++) {
recommendedProductsHTML += `<div>${recommendedProducts[i].title}</div>`;
}
$("#recommended_first").html(recommendedProductsHTML);
});
});

kendo clienttemplate with parameters

I am trying to set up a Kendo MVC Grid using client templates for a set of columns.
I have this and it is working:
columns.Bound(m => m.FC_Sun).ClientTemplate("# if(FC_Sun != Base_Sun) {#" + "<span style='color:red;'>#:FC_Sun # </span>" + "# } else {#" + "#: FC_Sun #" + "# } #");
However I would like to move this to a client template instead as I need to add quite a few more items to the column and an inline template just seems a little 'clunky'.
The question is, how can I do this with a single client template. I have an existing one which works for a particular column (the same one as above).
<script id="columnTemplate" type="text/kendo-tmpl">
#if(FC_Sun != Base_Sun){#
<span style='color:orange'>#:FC_Sun #</span>
#}else{#
<span>#: FC_Sun #</span>
#}#
</script>
As you can see this is very much tied to one column, doing it this way I would need to create 7 templates, one for each day of the week, which just seems overkill.
So is there a way to pass extra parameters to the template which tell it which values to use in the if statement..?
As it turns out there is a way to pass parameters to the template, in the grid:
"#=customColumnTemplate($.extend({}, data, { field: 'FC_Sun' }))#"
And the template:
<script id="columnTemplate" type="text/kendo-tmpl">
<p>#= data[field] #</p>
</script>
<script>
var customColumnTemplate = kendo.template($('#columnTemplate').html());
</script>
The way I actually did it in the end though was to skip the external template and use a function directly:
"#=customColumnTemplate(data, 'FC_Sun', 'Base_Sun')#"
.
function customColumnTemplate(data, field, baseField) {
var fc = data[field];
var fcBase = data[baseField];
if (fc != fcBase) {
return "<span style='color:red;'/>" + fc + "</span>";
}
return fc;
}
There isn't a way to pass parameters directly to a Kendo template, unfortunately. However, you could try using a switch statement in your template, and add an enumeration (or whatever would work) to your model for the switch key:
<script id="columnTemplate" type="text/kendo-tmpl">
# switch (DayofWeek) {
case "Sunday": #
<span style='color:orange;'>#:FC_Sun #</span>
# break; #
# case "Monday": #
<span style='color:red;'>#:FC_Mon #</span>
# break; #
...
# } #
</script>
This should allow you to "pass parameters" via the model, and control the appearance of the template per model instance.
Hope this helps.

Toggle Class Prototype Function

I'm trying to iterate over an array of elements, specified by class name. Then I want to use a function to toggle the class and change some text.
This does NOT work:
$$('.btn').forEach( setButtonLoadingStateOn, this );
setButtonLoadingStateOn = function( btn ) {
btn.toggleClassName('loading');
btn.disable();
btn.select('span span')[0].update( "please wait..." );
}
This does NOT work:
$$('.btn').each( function(btn) {
btn.addClassName('loading');
btn.disable();
btn.select('span span')[0].innerHTML = "please wait...";
});
This also does NOT work:
setButtonLoadingState( '.btn', 'start' );
setButtonLoadingState = function( btnClass, loadState ) {
btnElem = $$( btnClass );
btnElem.each(function( el ){
if ( loadState == 'start' ) {
el.addClassName( 'loading' );
el.disable();
el.select('span span')[0].innerHTML = "please wait...";
} else {
el.removeClassName( 'loading' );
el.enable();
el.select('span span')[0].innerHTML = "buy now";
}
});
}
If I console.log() the element, I get the object (or array) I'm expecting, so I don't know what's wrong.
I've also tried several SO answers, including this one: Add or remove class with prototype
In case it matters, the platform is Magento CE 1.8.0.2. How can I update these button elements using Prototype? Thanks.
~ edit ~
There are several HTML elements on the page. They all look like this:
<button type="button" title="buy now" class="button btn" onclick="productAddToCart(this)">
<span><span>Quick Buy</span></span>
</button>
Thanks so much to all who contributed. The AJAX request was returning a hyphenated key in the JSON response:
{"msg-html":"blah blah blah"}
Reading this from the response object as follows was the problem:
var ajaxResult = transport.responseText.evalJSON();
var ajaxMsg = ajaxResult.msg-html;
Hyphens are not allowed in JSON keys, instead the object needs to be accessed as follows:
var ajaxMsg = ajaxResult["msg-html"];
... or remove the hyphens! Thanks again to all.
Full credit to this dude/dudette: http://developer.appcelerator.com/question/120227/parsing-json-with-hyphenated-key-names

Prototype observers attached to a class firing multiple times

Thanks in advance for your help guys.
I consider myself pretty well-versed in jQuery but as I was helping my sister with her Prototype homework, this frustrated the crap out of me. She couldn't solve it in time so that's moot but for my sanity's sake, I hope you can tell me what's going on.
We were simply creating a netflix-style queue with add, reorder and delete through AJAX. The items were in a UL and had a delete link inside each LI with unique IDs to be used for deletion. Please don't fixate on why we were using text files to save data, etc. - her professor made that impractical choice a requirement, along with a few others...
JS:
function softRefresh() {
$$('.delete').invoke('observe','click',function() { taskDelete(this.id); });
Sortable.create("taskList", { onUpdate: function(list){ saveOrder(list); } });
}
function taskDelete(a) {
var tempArr = a.split('-');
var keyToDelete = tempArr[1];
var output;
var ajaxRequest = new Ajax.Request("todolist.php",
{
method: "post",
parameters: {
action: 'delete',
id: keyToDelete
},
onSuccess: function(response) {
$('taskList').update(response.responseText);
softRefresh();
}
});
}
PHP for the 'delete' action:
$jsonOutput = file_get_contents($myFile);
$fetchedArr = json_decode($jsonOutput);
$newArr = array();
foreach($fetchedArr as $key => $task) {
if(($key != $_POST['id'])) {
array_push($newArr, $task);
}
}
$jsonOutput = json_encode($newArr);
file_put_contents($myFile, $jsonOutput);
$output = '';
foreach($newArr as $key => $task) {
$output .= '<li id="list_'.$key.'">';
$output .= $task;
$output .= 'X';
$output .= '</li>';
}
echo $output;
The problem was that if I deleted, say, the 2nd item, all the following items would delete as well. Through firebug console I found out that this is because when you click any link of that class ('delete') all the following listeners fire, and keeps deleting the 2nd item off the new list. Can you tell me why and how I can set it so it only fires off the link you click? It drove me nuts all day. I'm used to having .click() on jQuery... much hatred for Prototype at the moment.
Thanks again!
JS:
You shouldn't need the softRefresh if you set the events well. Likewise, the <ul> element is never disposed nor replaced so only one Sortable should be necessary, there is no need to remake that each time.
Event.on('taskList', 'click', '.delete', taskDelete);
Sortable.create("taskList", { onUpdate: saveOrder });
function taskDelete(event, element) {
var id = element.id;
var tempArr = id.split('-');
var keyToDelete = tempArr[1];
new Ajax.Updater({success: 'taskList'}, "todolist.php",
{parameters: {
action: 'delete',
id: keyToDelete
}}
);
}
(Ajax objects in prototype are already POSTs so that doesn't need to be specified. Use of an Updater is neater too. There is little point in wrapping a function call in an anonymous function, it may be the jQuery way but it isn't adding any functionality, javascript functions are objects so use them as such.)
PHP:
I felt $newArr was a waste of a loop and some memory so here is a shorter way.
$jsonOutput = file_get_contents($myFile);
$fetchedArr = json_decode($jsonOutput);
unset($fetchArr[$_POST['id']]);
// Keys are preserved here, if you need to reorder use:
// $fetchedArr = array_values($fetchArr);
$jsonOutput = json_encode($fetchedArr);
file_put_contents($myFile, $jsonOutput);
foreach($fetchedArr as $key => $task) {
echo '<li id="list_'.$key.'">';
echo $task;
echo 'X';
echo '</li>';
}

Passing the signed_request along with the AJAX call to an ActionMethod decorated with CanvasAuthorize

This is a follow-up to AJAX Call Does Not Trigger Action Method When Decorated With CanvasAuthorize
So I found the following links and it seems that this is a common problem:
http://facebooksdk.codeplex.com/discussions/251878
http://facebooksdk.codeplex.com/discussions/250820
I tried to follow the advice by prabir but I couldn't get it to work...
Here's my setup:
I have the following snippet in the page where the button that triggers the whole post to facebook is located:
#if (!string.IsNullOrEmpty(Request.Params["signed_request"]))
{
<input type="hidden" id="signedReq" value="#Request.Params["signed_request"]" />
}
And then I have this snippet (inside a script tag inside the same page):
var signedRequest = $('#signedReq').val();
$('.facebookIcon').click(function () {
var thisItem = $(this).parent().parent();
var msg = thisItem.find('.compItemDescription').text();
var title = thisItem.find('.compareItemTitle').text();
var itemLink = thisItem.find('.compareItemTitle').attr('href');
var img = thisItem.find('img').first().attr('src');
postOnFacebook(msg, itemLink, img, title, signedRequest);
});
And finally, inside an external js file I have the following function:
/*Facebook post item to wall*/
function postOnFacebook(msg, itemLink, pic, itemTitle, signedReq) {
console.log(signedReq);
var siteUrl = 'http://www.localhost:2732';
$.ajax({
url: '/Facebook/PostItem',
data: {
'message': msg,
'link': siteUrl + itemLink,
'picture': siteUrl + pic,
'name' : itemTitle,
'signed_request': signedReq
},
type: 'get',
success: function(data) {
if(data.result == "success") {
alert("item was posted on facebook");
}
}
});
}
But signedReq is always undefined. And I'm not really sure I should be passing the 'signed_request' field inside the data object. Any thoughts?
Make sure you hidden input field is being populated.
Also, when you try to pull the ID of the input field via JQuery, you might not be referencing the proper element since .NET butcher's ID's of anything that's run on the server.
When I use the hidden input field trick, I set the jquery value like so:
var signedRequest = $('#<%=signedReq.ClientID %>').val();
This way, I'm getting the identifier that .NET is giving to the HTML element.
Hope that helps.
Just a guess - in your hidden field: id="signed_request" instead of id="signedReq"

Resources