jqGrid addRowData does not fire afterInsertRow - free-jqgrid

I'm upgrading my jqGrid from 4.7.1 to 4.14
This is my script for initializing the grid
jQuery("#detFlex62_1").jqGrid({
url: root + mod + '/detaillistview',
datatype: "local",
colNames:[' ', '<?=lang("users_company_code")?>', '<?=lang("users_company_name")?>', ' ', ' '],
colModel:[
{name:'myac', width:50, fixed:true, sortable:false, resize:false, formatter:'actions', formatoptions:{keys:true, editbutton : false, delbutton : false, delOptions: {reloadAfterSubmit:false},editOptions: {reloadAfterSubmit:false}}},
{name:'company_code',index:'company_code', width:100},
{name:'company_name',index:'company_name', width:100},
{name:'company_id',index:'company_id', width:100,hidden:true},
{name:'company_access_id',index:'company_access_id', width:100,hidden:true}
],
width: $('.body').width()-40,
height: 120,
pager: '#pagerFlex62_1',
sortname: 'user_id',
sortorder: "desc",
editurl: root + mod + '/detailpost',
caption:"<?=lang("users_title")?>",
onSelectRow: function(id){
activedf = "#detFlex62_1";
},
afterInsertRow: function (rowid) {
var grid = $(this),
iCol = getColumnIndexByName(grid,'myac'); // 'act' - name of the actions column
grid.find(">tbody>tr[id=" + rowid + "].jqgrow>td:nth-child(" + (iCol + 1) + ")")
.each(function() {
$("<div>",
{
title: "Edit",
mouseover: function() {
$(this).addClass('ui-state-hover');
},
mouseout: function() {
$(this).removeClass('ui-state-hover');
},
click: function(e) {
df_edit_1($(e.target).closest("tr.jqgrow").attr("id"));
/*alert("'Custom' button is clicked in the rowis="+
$(e.target).closest("tr.jqgrow").attr("id") +" !");*/
}
}
).css({float:"left"})
.addClass("ui-pg-div ui-inline-edit")
.append('<span class="ui-icon ui-icon-pencil"></span>')
.prependTo($(this).children("div"));
$("<div>",
{
title: "Delete",
mouseover: function() {
$(this).addClass('ui-state-hover');
},
mouseout: function() {
$(this).removeClass('ui-state-hover');
},
click: function(e) {
df_delete_1($(e.target).closest("tr.jqgrow").attr("id"));
/*alert("'Custom' button is clicked in the rowis="+
$(e.target).closest("tr.jqgrow").attr("id") +" !");*/
}
}
).css({float:"left"})
.addClass("ui-pg-div ui-inline-edit")
.append('<span class="ui-icon ui-icon-trash"></span>')
.prependTo($(this).children("div"));
});
}
});
jQuery("#detFlex62_1").jqGrid('navGrid','#pagerFlex62_1',{edit:false,del:false,search:false, addfunc: df_add_1, editfunc: df_edit_1});
And here is where I add new row into the grid
function df_addToJSON_1(form)
{
var idx = $('input[name=index]',form).val();
var id = $('input[name=id]',form).val();
var totalRows = jQuery("#detFlex62_1").jqGrid('getGridParam', 'records');
var data = {
company_code: $('input[name=company_code]',form).val(),
company_name: $('input[name=company_name]',form).val(),
company_id: $('input[name=company_id]',form).val(),
company_access_id: $('input[name=company_access_id]',form).val()
};
if (idx=='')
{
idx = getMaxRowId($('#detFlex62_1'));
$('#detFlex62_1').jqGrid("addRowData", idx + 1, data, "last");
}
else
{
$('#detFlex62_1').jqGrid("setRowData", idx, data);
}
//pCheckShow();
return false;
}
The new row is added, but without triggering the afterInsertRow event. Why is this happening? Is there a mistake in my code?

Free jqGrid supports afterAddRow, afterSetRow and afterDelRow callbacks, which will be called at the end of addRowData, setRowData and delRowData methods. The most new callbacks introduced by free jqGrid has one parameter (options, for example), which properties contains additional information. It allows to use only the properties, which one need, without require to insert unneeded first parameters if you need to use only the last parameter of old-style callback. Additionally, the new-style of callback parameters allows easy to extend the options in the future release of free jqGrid.
Thus you can, for example, change afterInsertRow: function (rowid) { to afterAddRow: function (options) { var rowid = options.rowid;
In general I would recommend you to make more changes in your code. What you do inside of afterInsertRow is creating custom action button. Your code is long and slow because jqGrid 4.7 had no simple way to create custom action button. Free jqGrid do supports the feature. I recommend you to read the wiki article, to examine the code of the demo, this one and the demos included in the answer. You will see that creating action buttons is very easy. You will have full control over onClick callback.

Related

Sharepoint: How to show AppendOnlyHistory on a display template in a cross-publishing scenario

The overarching requirement I am trying to implement is to show comments (made on a list, item by item basis).
I added the feature on the authoring side by enabling versioning on the list and adding a text field with the option "Append Changes to Existing Text" set to true.
This indeed allows me to comment on items and displays them chronologically, but on the authoring side only.
The issue is that the UI part will be done on another site collection and I can't find a straightforward way to get all comments there.
So far, every resource I have found points to
<SharePoint:AppendOnlyHistory runat="server" FieldName="YourCommentsFieldName" ControlMode="Display"/>
The thing is, I can't (don't know how to) use this inside a display template.
So far, I am getting all my data using the REST API, via
var siteUrl=_spPageContextInfo.webAbsoluteUrl.replace("publishing","authoring");
$.ajax({
url: siteUrl + "/_api/web/lists/getbytitle('" + listname + "')/items(" + id + ")",
type: 'GET',
async:false,
headers: {"accept": "application/json;odata=verbose",},
dataType: 'JSON',
success: function(json) {
console.log(json);
//var obj = $.parseJSON(JSON.stringify(json.d.results));
//alert(obj);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error :"+XMLHttpRequest.responseText);
}
});
What this gives me is the latest comment only. I need a simple way to get a hold of the entire thread.
I ended up using javascript object model to get them like so:
function GetComments(listname, itemId) {
var siteUrl = _spPageContextInfo.webAbsoluteUrl.replace("publishing", "authoring");
if ($(".comments-history").length) {
$().SPServices({
operation: "GetVersionCollection",
async: false,
webURL: siteUrl,
strlistID: listname,
strlistItemID: itemId,
strFieldName: "Comments",
completefunc: function (xData, Status) {
$(xData.responseText).find("Version").each(function (data, i) {
var xmlComment = $(this)[0].outerHTML;
var arr = xmlComment.split(/comments|modified|editor/g);
var comment = arr[1].trim().substring(2, arr[1].length-2);
var dateSt = Date.parse((arr[2].substring(1, arr[2].length)).replace('/"', ''));
var user = getUsername(arr[3]);
var st = "<div class='comment-item'><div class='comment-user'>" + user + "(" + FormatDate(dateSt) + ")</div>";
st += "<div class='comment-text'>" + comment + "</div></div>";
$(".comments-history").append(st);
});
}
});
}
}
the parsing could be better, but this is just an initial working idea

Sitecore experience editor button triggering .aspx pop up page

Is it possible to make sitecore experience editor ribbon button trigger .aspx page in pop up window? It was possible before speak-ui was introduced by assigning a command to the button's click field.
There is a lot of tutorials describing how to use XML controls (e.g. http://jockstothecore.com/sitecore-8-ribbon-button-transfiguration/) but I can't find any information about triggering .aspx page.
My command looks like this:
<command name="item:showDashboard" type="Sitecore.Starterkit.customcode.Reports, MyProject" />
In the tutorial you posted I will just modify the code snippets to reflect what you need to do. (Considering you have done everything else). In the part Spell Two
In the command class you should do something like this (if you need to wait for postback):
public override void Execute(CommandContext context)
{
Assert.ArgumentNotNull((object) context, "context");
Context.ClientPage.Start((object) this, "Run", context.Parameters);
}
protected static void Run(ClientPipelineArgs args)
{
Assert.ArgumentNotNull((object) args, "args");
SheerResponse.ShowModalDialog(new UrlString("/YOURURL.aspx").ToString(), true);
args.WaitForPostBack();
}
If you just want to show something :
public override void Execute(CommandContext context)
{
Assert.ArgumentNotNull((object)context, "context");
if (context.Items.Length != 1)
return;
Item obj = context.Items[0];
UrlString urlString = new UrlString("/YOURURL.aspx");
urlString["fo"] = obj.ID.ToString();
urlString["la"] = obj.Language.ToString();
urlString["vs"] = obj.Version.ToString();
string str = "location=0,menubar=0,status=0,toolbar=0,resizable=1,getBestDialogSize:true";
SheerResponse.Eval("scForm.showModalDialog('" + (object)urlString + "', 'SitecoreWebEditEditor', '" + str + "');");
}
For the javascript:
define(["sitecore"], function (Sitecore) {
Sitecore.Commands.ScoreLanguageTools = {
canExecute: function (context) {
return true; // we will get back to this one
},
execute: function (context) {
var id = context.currentContext.itemId;
var lang = context.currentContext.language;
var ver = context.currentContext.version;
var path = "/YOURURL.aspx?id=" + id + "&lang=" + lang + "&ver=" + ver;
var features = "dialogHeight: 600px;dialogWidth: 500px;";
Sitecore.ExperienceEditor.Dialogs.showModalDialog(
path, '', features, null,
function (result) {
if (result) {
window.top.location.reload();
}
}
);
}
};
});

Simple boolean conditional from AJAX (ember.js)

I'm trying to do something which must be really simple to accomplish in Ember.
I want to show a button in my template based on the boolean state of a property:
{{#if canFavoriteTag}}
{{d-button action="favoriteTag" label="tagging.favorite" icon="star-o" class="admin-tag favorite-tag"}}
{{else}}
{{d-button action="unFavoriteTag" label="tagging.unfavorite" icon="star-o" class="admin-tag favorite-tag tag-unfavorite"}}
{{/if}}
I have created a property called canFavoriteTag with a function which I want to return true or false to the template based on whether the user can favorite the tag or not:
export default Ember.Controller.extend(BulkTopicSelection, {
canFavoriteTag: function() {
const self = this;
var ticker = this.get('tag.id');
console.log('checking can fav stock:' + ticker);
Discourse.ajax("/stock/get_users_favorite_stocks", {
type: "GET",
}).then(function(data) {
var favable = true;
for (var i = data.stock.length - 1; i >= 0; i--) {
var stock = jQuery.parseJSON(data.stock[i]);
if(ticker.toLowerCase() == stock.symbol.toLowerCase()) { console.log(ticker + ' is a favorite stock: ' + stock.symbol.toLowerCase()); favable = false; }
}
console.log(favable);
return favable;
});
}.property('canFavoriteTag') <-- unsure about this?
...
When the page loads, the wrong button shows (always the "false" one).. I see in the console that the favable variable gets set to false when the ajax call completes, but the button never changes. How do I get it to show the right button based on the function? Do I need to use a promise? If so, how?

Jquery Tool: Keep selected tab on refresh or save data

I am using jquery tool for tab Ui,
Now I want to keep tab selected on page reload. Is there any way to do that? below is my code
$(function() {
// setup ul.tabs to work as tabs for each div directly under div.panes
$("ul.tabs").tabs("div.panes > div");
});
Here is a simple implementation of storing the cookie and retrieving it:
function getCookie(c_name) {
var i, x, y, ARRcookies = document.cookie.split(";");
for (i = 0; i < ARRcookies.length; i++) {
x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
x = x.replace(/^\s+|\s+$/g, "");
if (x == c_name) {
return unescape(y);
}
}
}
function setCookie(c_name, value, exdays) {
var exdate = new Date();
exdate.setDate(exdate.getDate() + exdays);
var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString());
document.cookie = c_name + "=" + c_value;
}
Then, to save/retrieve cookie data with jQuery UI Tabs:
$(function() {
// retrieve cookie value on page load
var $tabs = $('ul.tabs').tabs();
$tabs.tabs('select', getCookie("selectedtab"));
// set cookie on tab select
$("ul.tabs").bind('tabsselect', function (event, ui) {
setCookie("selectedtab", ui.index + 1, 365);
});
});
Of course, you'll probably want to test if the cookie is set and return 0 or something so that getCookie doesn't return undefined.
On a side note, your selector of ul.tabs may be improved by specifying the tabs by id instead. If you truly have a collection of tabs on the page, you will need a better way of storing the cookie by name - something more specific for which tab collection has been selected/saved.
UPDATE
Ok, I fixed the ui.index usage, it now saves with a +1 increment to the tab index.
Here is a working example of this in action: http://jsbin.com/esukop/7/edit#preview
UPDATE for use with jQuery Tools
According the jQuery Tools API, it should work like this:
$(function() {
//instantiate tabs object
$("ul.tabs").tabs("div.panes > div");
// get handle to the api (must have been constructed before this call)
var api = $("ul.tabs").data("tabs");
// set cookie when tabs are clicked
api.onClick(function(e, index) {
setCookie("selectedtab", index + 1, 365);
});
// retrieve cookie value on page load
var selectedTab = getCookie("selectedtab");
if (selectedTab != "undefined") {
api.click( parseInt(selectedTab) ); // must parse string to int for api to work
}
});
function getCookie(c_name) {
var i, x, y, ARRcookies = document.cookie.split(";");
for (i = 0; i < ARRcookies.length; i++) {
x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
x = x.replace(/^\s+|\s+$/g, "");
if (x == c_name) {
return unescape(y);
}
}
}
function setCookie(c_name, value, exdays) {
var exdate = new Date();
exdate.setDate(exdate.getDate() + exdays);
var c_value = escape(value) + ((exdays === null) ? "" : "; expires=" + exdate.toUTCString());
document.cookie = c_name + "=" + c_value;
}
Here is a working (unstyled) example: http://jsbin.com/ixamig/12/edit#preview
Here is what I see in Firefox when inspecting the cookie from the jsbin.com example:
This is what worked for me... at least I haven't run into any issues yet:
$('#tabs').tabs({
select: function (event, ui)
{
$.cookie('active_tab', ui.index, { path: '/' });
}
});
$('#tabs').tabs("option", "active", $.cookie('active_tab'));
I'm using: jQuery 1.8.2, jQuery UI 1.9.1, jQuery Cookie Plugin.
I set the "path" because in C# I set this value in a mvc controller which defaults to "/". If the path doesn't match, it wont overwrite the existing cookie. Here is my C# code to set the value of the same cookie used above:
Response.Cookies["active_tab"].Value = "myTabIndex";
Edit:
As of jQuery UI 1.10.2 (I just tried this version, not sure if it's broken in previous versions), my method doesnt work. This new code will set the cookie using jQuery UI 1.10.2
$('#tabs').tabs({
activate: function (event, ui) {
$.cookie('active_tab', ui.newTab.index(), { path: '/' });
}
});
The easiest way to survive between page refresh is to store the selected tab id in session or through any server-side script.
Only methods to store data on client side are: Cookies or localStorage.
Refer to thread: Store Javascript variable client side

Sencha Touch - List with Search-Field (XMLStore)

I have a external XML-file which I use to filling my list. This works great.
But now I want to filter(search) the XML-data with a search-field on top of the list.
My List looks like this:
ToolbarDemo.views.Beitrage = Ext.extend(Ext.List, {
title: "Beiträge",
iconCls: "btnbeitraege",
id: 'disclosurelist',
store: storeXML,
itemTpl: '<div class="contact"><img src="{bild}" width="96" height="52" border="0"/> {titel}</div>',
grouped: true,
onItemDisclosure: function(record, btn, index) {
Ext.Msg.alert('', '<video width="200" height="200" x-webkit-airplay="allow" poster="'+ record.get('bild') +'" controls="controls" id="video_player" style="" tabindex="0"><source src="'+ record.get('video') +'"></source></video>', Ext.emptyFn);
} });storeXML.load();
And my XML-input looks like this:
Ext.regModel('beitrag', {fields: ['datum', 'titel', 'video', 'bild']});
var storeXML = new Ext.data.Store({
model: 'beitrag',
sorters: [
{
property : 'Datum',
direction: 'DESC'
}],
getGroupString : function(record) {
var month = record.get('datum').split('-');
return month[2] + '.' + month[1] + '.' + month[0];
},
method: 'GET',
proxy: {
url: 'beitraege.xml',
type: 'ajax',
reader: {
type: 'xml',
record: 'beitrag',
root: 'beitraege'
},
}});
I know it's an old question, but I have managed to filter my list using a filter function in it's store. Here is how I did:
In my view I have a text field (xtype: 'searchfield').
In the controller for this view I have registered for 2 events by using the 'control' property
control: {
'searchfield': {
clearicontap: 'onSearchClearIconTap',
keyup: 'onSearchKeyUp'
}
}
onSearchKeyUp function looks like this (note: the field I'm going to filter is 'docName')
onSearchKeyUp: function(field)
{
var value = field.getValue(),
store = this.getMaster().getStore();
store.clearFilter();
if (value)
{
var searches = value.split(' '),
regexps = [],
i;
for (i = 0; i < searches.length; i++)
{
//if it is nothing, continue
if (!searches[i]) continue;
//if found, create a new regular expression which is case insenstive
regexps.push(new RegExp(searches[i], 'i'));
}
store.filter(function(record)
{
var matched = [];
//loop through each of the regular expressions
for (i = 0; i < regexps.length; i++)
{
var search = regexps[i],
didMatch = record.get('docName').match(search);
//if it matched the first or last name, push it into the matches array
matched.push(didMatch);
} //if nothing was found, return false (dont so in the store)
if (regexps.length > 1 && matched.indexOf(false) != -1) {
return false;
} else {
//else true true (show in the store)
return matched[0];
}
});
}
}
The 'onSearchClearIconTap' function instead is called when the user taps on the clear icon that is the 'X' included in the searchfield component, that clears the text, so the only thing we want to do is to reset the filter for our list:
onSearchClearIconTap: function()
{
this.getMaster().getStore().clearFilter();
}