I try to apply this example with another way. When I try it on console.log it seems run without error but when I do it on function(){}, it turns error all grid method is undefined such:
Uncaught TypeError: Cannot call method 'getView' of undefine.
The function:
onTextFieldChange = function () {
var grid = Ext.getCmp('grid'),
value = Ext.getCmp('gridfield'),
view = grid.getView(),
columns = grid.getColumns();
view.refresh();
grid.searchValue = value.getValue();
grid.matches = [];
grid.currentIndex = null;
if (grid.searchValue !== null) {
grid.store.each(function (record, index) {
var node = view.getNode(record),
count = 0;
if (node) {
Ext.Array.forEach(columns, function (column) {
var cell = Ext.fly(node).down(column.getCellInnerSelector(), true),
matches,
cellHTML,
seen;
if (cell) {
matches = cell.innerHTML.match(grid.tagsRe);
cellHTML = cell.innerHTML.replace(grid.tagsRe, grid.tagsProtect);
cellHTML = cellHTML.replace(grid.searchRegExp, function (m) {
++count;
if (!seen) {
grid.matches.push({
record: record,
column: column
});
seen = true;
}
return '<span class="' + grid.matchCls + '" style="font-weight: bold;background-color: yellow;">' + m + '</span>';
}, grid);
Ext.each(matches, function (match) {
cellHTML = cellHTML.replace(grid.tagsProtect, match);
});
// update cell html
cell.innerHTML = cellHTML;
}
});
}
});
}
};
The event:
xtype: 'textfield',
name: 'searchField',
id: 'txtfield',
hideLabel: true,
width: 200,
change: onTextFieldChange()
Any suggestions?
I answer my own question if there is none, this is onTextFieldChange() method
onTextFieldChange = function () {
var me = Ext.getCmp('grid'),
count = 0;
me.view.refresh();
me.searchValue = getSearchValue();
me.indexes = [];
me.currentIndex = null;
if (me.searchValue !== null) {
me.searchRegExp = new RegExp(me.searchValue, 'g' + (me.caseSensitive ? '' : 'i'));
me.store.each(function (record, idx) {
var td = Ext.fly(me.view.getNode(idx)).down('td'),
cell, matches, cellHTML;
while (td) {
cell = td.down('.x-grid-cell-inner');
matches = cell.dom.innerHTML.match(me.tagsRe);
cellHTML = cell.dom.innerHTML.replace(me.tagsRe, me.tagsProtect);
// populate indexes array, set currentIndex, and replace wrap matched string in a span
cellHTML = cellHTML.replace(me.searchRegExp, function (m) {
count += 1;
if (Ext.Array.indexOf(me.indexes, idx) === -1) {
me.indexes.push(idx);
}
if (me.currentIndex === null) {
me.currentIndex = idx;
}
return '<span class="' + me.matchCls + '">' + m + '</span>';
});
// restore protected tags
Ext.each(matches, function (match) {
cellHTML = cellHTML.replace(me.tagsProtect, match);
});
// update cell html
cell.dom.innerHTML = cellHTML;
td = td.next();
if (me.currentIndex !== null) {
me.getSelectionModel().select(me.currentIndex);
}
}
}, me);
}
// no results found
if (me.currentIndex === null) {
me.getSelectionModel().deselectAll();
}
};
Related
Desired Functionality: On selecting a checkbox, a span is created with an id & data attribute same as the checkbox and appended to a div. On clicking the 'x' on this span should uncheck the checkbox and remove the span as well.
Issue: On selecting the checkbox, an additional span with an 'undefined' label is created.
JSFIDDLE
var filtersApplied = [];
$('.ps-sidebar').on('change', 'input[type=checkbox]', function () {
var me = $(this);
console.log('me', me);
if (me.prop('checked') === true) {
filtersApplied.push([
...filtersApplied,
{ id: me.attr('id'), data: me.attr('data-filter-label') }
]);
} else {
filtersApplied = filtersApplied.map(function (item, index) {
return item.filter(function (i) {
return i.id !== item[index].id;
});
});
}
if (filtersApplied.length === 0) {
$('.ps-plans__filters').hide();
$('.ps-plans__filters-applied').html('');
} else {
$('.ps-plans__filters').show();
var filtersAppliedHtml = '';
filtersApplied.map(function (elements) {
console.log('items', elements);
return elements.map(function (el, i) {
console.log('item', el);
return (filtersAppliedHtml +=
'<span class="ps-plans__filter" id="' + el.id + '_' + i +'">' +el.data +
'<span class="icon-remove-circle remove-filter" data-filter="' +el.data +'"> X</span></span>');
});
});
console.log('filtersAppliedHtml', filtersAppliedHtml);
console.log($('.ps-plans__filters-applied').html(filtersAppliedHtml));
}
});
Your undefined label is because of the ...filtersApplied
if (me.prop('checked') === true) {
filtersApplied.push([
//this ...filtersApplied
{ id: me.attr('id'), data: me.attr('data-filter-label') }
]);
Note that filtersApplied is an array and you're making a push(), this method inserts a value in the end of the array, so your ...filtersApplied makes no sense. Just remove it and you'll be fine. You can se more here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
there are few thing that need to be fixed.
when adding an element you should not push filtersApplied along with new object. instead you better do arr = [...arr, obj];
when remove an item you could apply a filter instead based on me.attr('id'). with map you would get undefined values;
after that you would map only once to build your html content, not twice;
var filtersApplied = [];
$('.ps-sidebar').on('change', 'input[type=checkbox]', function () {
var me = $(this);
if (me.prop('checked') === true) {
filtersApplied = [
...filtersApplied,
{ id: me.attr('id'), data: me.attr('data-filter-label') }
];
} else {
filtersApplied = filtersApplied.filter(function (item, index) {
return me.attr('id') !== item.id;
});
}
if (filtersApplied.length === 0) {
$('.ps-plans__filters').hide();
$('.ps-plans__filters-applied').html('');
} else {
$('.ps-plans__filters').show();
var filtersAppliedHtml = '';
filtersApplied.map(function (el, i) {
return (filtersAppliedHtml +=
'<span class="ps-plans__filter" id="' +
el.id +
'_' +
i +
'">' +
el.data +
'<span class="icon-remove-circle remove-filter" data-filter="' +
el.data +
'"> X</span></span>');
});
$('.ps-plans__filters-applied').html(filtersAppliedHtml);
}
});
For the life of me I cannot see the suttle difference between copied code. The _getMiscData method in a child widget apparently doesn't exist according to the parent widget. Can someone explain this?
I tried different method names in case I was using a reserved word. I tried private and public method with same result.
$(function() {
$.widget("custom.textquestion", $.custom.base, {
_create: function() {
this.element.data("_getControlValue", this.getControlValue());
},
getControlValue: function() {
this.element.attr("usersanswer", this.getResponseJSON());
},
_getAnswerSelection: function(answer) {
var qname = this._getQuestionName();
var type = this.getType();
return '<div class="radio span6"><label><input type="text" class="answerfield" name="optradio-' + qname + '" value="' + answer.answertext + '"></label></div>'
},
_getAnswersDiv: function(answers) {
// DIV is required for wrapping around list of answers
// so that they can be added all at once.
var answerdivs = '<div class="answerlist">'
for (k = 0; k < answers.length; k++) {
answerdivs += this._getAnswerSelection(answers[k]);
}
answerdivs += '</div>';
return answerdivs;
},
_getPopulatedEditor: function(answers) {
var editanswerdiv = "";
for (p = 0; p < answers.length; p++) {
editanswerdiv += '<label>Default</label><input type="text" onblur="savequestiondata()" identifier="' + answers[p].answerid + '" name="editanswer' + this._getQuestionName(this.options.questioncontrol) + '" size="20" value="' + answers[p].answertext + '"/><br/>'
}
return editanswerdiv;
},
_getAnswersJSON: function(div) {
var answers = [];
$(div).find("input[name='editanswer" + this._getQuestionName(this.options.questioncontrol) + "']").each(function(i, u) {
var answer = {
answerid: $(this).attr('identifier'),
answertext: $(this).val(),
answerorder: 0,
rating: 0
};
answers.push(answer);
});
return answers;
},
_setAnswerJSON: function(answer) {
answer = answer.replace(/['"]+/g, '');
this.options.questioncontrol.find("input[name='optradio-" + this._getQuestionName() + "']").val(answer);
return true;
},
getResponseJSON: function() {
qname = this._getQuestionName();
console.log("The control name is " + qname);
var answer = this.options.questioncontrol.find("input[name='optradio-" + qname + "']").val();
console.log("The answer is " + answer);
return answer;
},
_refresh: function() {
qname = this._getQuestionName(this.options.questioncontrol);
// Create the divs for the answer block, then
// append to this question as the list of answers.
var answers = this._getStoredData().data.answers;
var answerhtml = this._getAnswersDiv(answers);
this.options.questioncontrol.find(".answer-list").html("");
this.options.questioncontrol.find(".answer-list").append(answerhtml);
// Get the explanation text and add to control.
var explanation = this._getStoredData().data.explanation;
this.options.questioncontrol.find(".explanation").text(explanation);
// Populate the editor controls with the answers that
// are already stored - ready for editing.
var editanswerhtml = this._getPopulatedEditor(answers);
this.options.questioncontrol.find(".editanswers").html("");
this.options.questioncontrol.find(".editanswers").append(editanswerhtml);
this.options.questioncontrol.find(".notes").text(explanation);
},
_getQuestionText: function(div) {
var qtext;
$(div).find("input[name='questiontextedit']").each(function() {
qtext = $(this).val();
});
return qtext;
},
_getMiscData: function() {
var info = [this.options.questioncontrol.find(".email-mask").val()];
return info;
},
_setOtherData: function(info) {
if (info.emailmask == "true")
this.options.questioncontrol.find(".email-mask").attr("checked", "checked");
else
this.options.questioncontrol.find(".email-mask").attr("checked", "");
},
_getExplanationText: function(div) {
var etext = $(div).find(".notes").val();
return etext;
}
});
});
$(function() {
$.widget("custom.base", {
// default options
options: {
questioncontrol: this,
questiondata: null,
_storedData: [],
},
_create: function() {
},
_refresh: function() {
},
getEditedAnswers: function(div) {
// Get the set of answers that were edited.
if (!div)
div = this.options.questioncontrol;
var answersresult = this._getAnswersJSON(div);
var question = this._getQuestionText(div);
var typename = this.getType();
var qname = this._getQuestionName(this.options.questioncontrol);
var pagenumber = this._getStoredData(qname).data.pagenumber;
var order = this._getStoredData(qname).data.order;
var explanation = this._getExplanationText(div);
var otherdata = this._getMiscData();
var result = {
title: question,
type: typename,
pageid: pagenumber,
qname: qname,
answers: answersresult,
questionorder: order,
explanation: explanation,
otherdata: otherdata
};
return result;
},
getType: function() {
return $(this.options.questioncontrol).attr('id');
},
setData: function(questiondata) {
// Set the title for the question. I.e, the text
// for the question.
this.options.questioncontrol.find(".questiontitle").text(questiondata.title);
this.options.questioncontrol.find("input[name='questiontextedit']").val(questiondata.title);
this.options.questioncontrol.find(".notes").text(questiondata.explanation);
// Store the data into datastore.
var stored = 0;
if (this._getStoredData(questiondata.qname) == null) {
this.options._storedData.push({
qname: questiondata.qname,
data: questiondata
});
} else {
var datastored = this._getStoredData(questiondata.qname);
datastored.data = questiondata;
}
if (questiondata.otherdata)
this._setOtherData(questiondata.otherdata);
this._refresh();
},
setAnswer: function(answer) {
this._setAnswerJSON(answer);
},
_getQuestionName: function() {
return this.options.questioncontrol.find('.questionname').val();
},
_getStoredData: function() {
var qname = this._getQuestionName(this.options.questioncontrol);
for (p = 0; p < this.options._storedData.length; p++) {
if (this.options._storedData[p].qname == qname)
return this.options._storedData[p];
}
return null;
},
});
});
The custom.base widget shouldn't return with "this.getMiscData is not a function"
In this DEMO you can see the red <b> tags are showing a different index from the black ones below, this happens why I am trying to use the same index for both <li> and parents <ul>, but something is not working properly... it seems like, only at the very first step, the index counting in skipped and all the remaining index then is "slipped" one step forward, so they are not matching...
var object = {
sometdhing: {
sometfhing: {
somgething: 'text',
someathing: 'text'
},
someathing: {
somefthing: 'text',
sometghing: 'text'
}
},
someathing: {
somethfing: {
somgething: 'text',
somethihng: 'text'
},
somejthing: {
somethhing: 'text',
somfething: 'text'
}
}
}
var indexes = [];
var object2ul = function (data, level) {
var keys = Object.keys(data);
var json = '<ul>'+ '<b style="color:red">'+level+'</b>';
for (var i=0; i<keys.length; ++i) {
var key = keys[i];
indexes.push(i);
json += '<li>' + "<b>" + indexes.join('_') + "</b> - " + key;
if (typeof(data[key]) === 'object') {
json += object2ul(data[key], indexes.join('_'));
} else {
json += '<ul><li>' + data[key] + "</li></ul>";
}
json += "</li>";
indexes.pop();
}
return json + "</ul>";
}
document.body.innerHTML = object2ul(object, 0);
Please help...
Css did help
Code: http://jsfiddle.net/18obnr9L/3/
here i construct elements from object like ul, li, ol...
var data = {
sometdhing: {
sometfhing: {
somgething: 'atext1',
someathing: 'atext2'
},
someathing: {
somefthing: 'atexta1',
sometghing: 'atexta2'
}
},
someathing: {
somethfing: {
somgething: 'btext1',
somethihng: 'btext2'
},
somejthing: {
somethhing: 'btexta1',
somfething: 'btexta2'
}
}
};
list(data);
function list(data) {
var ul = document.createElement('ol'),
li = document.createElement('li')
main = ul.cloneNode();
getProps(main, data);
document.body.appendChild(main);
function getProps(parent, d) {
for (var i in d) {
if (typeof d[i] == "string") {
addLi(parent, d[i], i);
} else if (d[i] instanceof Object) {
var pli = addLi(parent, '', i);
var temp = ul.cloneNode();
getProps( temp, d[i] )
pli.appendChild(temp);
parent.appendChild(pli);
}
}
}
function createUli(val){
var ul = document.createElement('ul');
var l = li.cloneNode();
ul.appendChild(l);
l.innerText = val;
return ul;
}
function addLi(p, val, i) {
var ele = li.cloneNode();
ele.innerText = i;
if (val != '') ele.appendChild(createUli(val));
p.appendChild(ele);
return ele;
}
}
I am currently working with example 5: http://mleibman.github.io/SlickGrid/examples/example5-collapsing.html so that I can implement collapsing in my own slickgrid. However I am having trouble doing this and was wondering if there is some tutorial I can look at or if someone has done this and can give me a few pointers. The following is some test code that I have been working with to get this to work, without a lot of luck
<script>
var grid;
var data = [];
//this does the indenting, and adds the expanding and collapsing bit - has to go before creating colums for the grid
var TaskNameFormatter = function (row, cell, value, columnDef, dataContext) {
value = value.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
var spacer = "<span style='display:inline-block;height:1px;width:" + (15 * dataContext["indent"]) + "px'></span>";
var idx = dataView.getIdxById(dataContext.id);
if (data[idx + 1] && data[idx + 1].indent > data[idx].indent) {
if (dataContext._collapsed) {
return spacer + " <span class='toggle expand'></span> " + value;
} else {
return spacer + " <span class='toggle collapse'></span> " + value;
}
} else {
return spacer + " <span class='toggle'></span> " + value;
}
};
var columns = [
{id: "title", name: "title", field: "title", width: 150, formatter: TaskNameFormatter},
{id: "duration", name: "Duration", field: "duration"},
{id: "start", name: "Start", field: "start"},
{id: "finish", name: "Finish", field: "finish"}
];
var options = {
enableColumnReorder: false
};
var searchString = "";
function myFilter(item) {
if (searchString != "" && item["title"].indexOf(searchString) == -1) {
return false;
}
if (item.parent != null) {
var parent = data[item.parent];
while (parent) {
if (parent._collapsed || (searchString != "" && parent["title"].indexOf(searchString) == -1)) {
return false;
}
parent = data[parent.parent];
}
}
return true;
}
$(function () {
var indent = 0;
var parents = [];
for (var i = 0; i < 3; i++) {
var d = (data[i] = {});
var parent;
d["id"] = "id_" + i;
if (i===0){
d["title"] = "1st Schedule";
}else if(i===1){
d["title"] = "1st Schedule Late";
}else {
d["title"] = "1st Schedule Early Leave";
}
if (i===0){
parent =null;
}
if (i===1){
parent = parents[parents.length - 1];
indent++;
}
if (i===2){
indent++;
parents.push(1);
}
if (parents.length > 0) {
parent = parents[parents.length - 1];
} else {
parent = null;
}
d["indent"] = indent;
d["parent"] = parent;
d["duration"] = "5 days";
d["start"] = "01/01/2013";
d["finish"] = "01/01/2013";
}
/* **************Adding DataView for testing ******************/
dataView = new Slick.Data.DataView();
dataView.setItems(data);
dataView.setFilter(myFilter); //filter is needed to collapse
/* ************** DataView code end ************************* */
grid = new Slick.Grid("#myGrid", dataView, columns, options);
//this toggles the collapse and expand buttons
grid.onClick.subscribe(function (e, args) {
if ($(e.target).hasClass("toggle")) {
var item = dataView.getItem(args.row);
if (item) {
if (!item._collapsed) {
item._collapsed = true;
} else {
item._collapsed = false;
}
dataView.updateItem(item.id, item);
}
e.stopImmediatePropagation();
}
});
//this is needed for collapsing to avoid some bugs of similar names
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render();
});
})
</script>
I strongly suggest you to look into the grouping example instead, it's also with collapsing but is made for grouping, which is 90% of what people want and since couple months can also do multi-column grouping. You can see here the SlickGrid Example Grouping then click on these buttons (1)50k rows (2)group by duration then effort-driven (3)collapse all groups...then open first group and you'll see :)
As for your code sample, I replaced the example with your code and it works just as the example is...so?
I am using "jQuery Easy UI" in my website. I need treegrid in a page with checkbox for each row (The same way as "jQuery Easy UI"-tree provedes).
I needs the same tree to be appear with grid in treegrid widget, instead of
Any suggestion is most welcome....
thanks....
add the following code to have checkbox column to your tree table
$(function() {
columns:[[
{field:'code',title:'Code',width:100,align:'left'},
{field:'name',title:'Name',width:100,align:'right'},
{field:'addr',title:'choose',width:80},
{field:'col4',title:'col4',width: 100,
editor: {
type: 'checkbox',
options: {on: '1', off: '0'}
},
formatter: function (value, row) {
if (! row.leaf) {
if (value == 1) {
return '<img src="../resources/image/checked.jpg"/>';
} else {
return '<img src="../resources/image/unchecked.jpg"/>';
}
} else {
return'';
}
}
}
]],
//Edit the end of the line,
// use click event first perform onAfterEdit event before the event trigger
onClickRow: function (row) {
var rowIndex = row.id;
if (lastIndex != rowIndex) {
$('#tablegridJS').treegrid('endEdit', lastIndex);
}
},
//Line editing,
//use double-click event
onDblClickRow: function (row) {
var rowIndex = row.id;
if (lastIndex != rowIndex) {
$('#tablegridJS').treegrid('endEdit', lastIndex);
$('#tablegridJS').treegrid('beginEdit', rowIndex);
lastIndex = rowIndex;
}
},
OnBeforeEdit: function (row) {
console.log(row);
beforEditRow(row); // Here are the main steps and code functions
},
OnAfterEdit: function (row, changes) {
console.log(change);
var rowId = row.id;
$.ajax ({
url: "saveProductConfig.action",
data: row,
success: function (text) {
$.Messager.alert ('message', 'text', 'info');
}
});
},
onClickCell: function(field, row) {
if(field=='col4'){
var rowIndex = row.id;
if (lastIndex != rowIndex) {
$('#tablegridJS').treegrid('endEdit', lastIndex);
$('#tablegridJS').treegrid('beginEdit', rowIndex);
console.log($('#tablegridJS').treegrid('options'));
options = $('#tablegridJS').treegrid('getEditor',{
index:row.id, // pass the editing row id, defined via 'idField' property
field:'col4'
});
//console.log($(options.target).attr('checked',true));
console.log(options.target);
if(options.oldHtml=='<img src="../resources/image/unchecked.jpg">'){
$(options.target).attr('checked',true);
}else if(options.oldHtml=='<img src="../resources/image/checked.jpg">'){
$(options.target).attr('checked',false);
}
lastIndex = rowIndex;
}
}
}
});
function beforEditRow (row) { // This is the core, very useful if the same needs, then you can learn to achieve
//check box
var libraryCoclum = $('#tablegridJS').treegrid('getColumnOption', 'col4');
//checkbox object
var checkboxOptionsObj = new Object ();
checkboxOptionsObj.on = '1 ';
checkboxOptionsObj.off = '0 ';
//add checkbox object on edit
var checkboxEditorObj = new Object ();
checkboxEditorObj.type = 'checkbox';
checkboxEditorObj.options = checkboxOptionsObj;
//ckeck whether to make checkbox or combo box editable
if (row.leaf) {
libraryCoclum.editor = null;
typeCoclum.editor = comboboxEditorObj;
} else {
libraryCoclum.editor = checkboxEditorObj;
typeCoclum.editor = null;
}
}
$("#bteasyui").click(function(){
var dataSelected = "";
//$("#tablegridJS").treegrid('selectAll');
nodes = $("#tablegridJS").treegrid('getSelection');
console.log(nodes);
$('#tablegridJS').treegrid('beginEdit', nodes.id);
dataSelected = $("#tablegridJS").treegrid("check",'01');
console.log($("#tablegridJS").treegrid('getChecked'));
});
});