How to operate on an element inside jquery-bootgrid formatters - javascript

Suppose I have an bootgrid formatters like this:
$(document).ready(function () {
//bootgrid
$("#bootgrid-issues").bootgrid({
...
formatters: {
product: function (column, row){
return "<p class='per_online_issue_id'>" + row.product["product_name"] +"</p>";
},
category: function (column, row){
return "<p>" + row.category["category_name"] +"</p>";
},
},
});
And I want it to print an "hello" if the per_online_issue_id element clicked.
But it doesn't work as expected. Have I missed something? Here is how I do this, I wrote it right after the formatters.
$('.per_online_issue_id').click(function () {
console.log("hello")
});

Finally I myself figured out how to do this by returning javascript.
First: Return Javascript from the formatters of bootgrid.
product: function (column, row){
return "<a href=\"javascript:void(0)\" onclick=my_function(\'"+row.product["product_name"]+"\'+ "</a>";
},
Second: Call the returned my_function to operate the element you want.
<script>
function my_function(product_name) {
alert("product_name returned from bootgrid: " + production_name);
}
</script>

Related

jQuery object outputting undefined

I'm having a hard time having a function return the output using innerHTML call in JavaScript.
It is outputting as 'Undefined':
Here is the code:
$(document).ready(function(){
$pnp.setup({
baseUrl: "https://fh126cloud.sharepoint.com/TrainingResourceCenter/O365Training"
});
$pnp.sp.web.lists.getByTitle("O365RoadMap").items.get().then(function(items) {
console.log(items);
var result = items.map(item => {
return {
Title: item.Title,
Description: item.Description,
Link: item.Link
}
});
var $table = roadMapDisplay(result);
console.log($table);
document.getElementById('title').innerHTML = $table.innerHTML;
});
function roadMapDisplay(items) {
var table = $('<table/>');
items.forEach(item => {
table.append('<tr/>');
table.append(`<td>${item.Title}</td>`);
table.append(`<td>${item.Description}</td>`);
table.append(`<td>${item.Link}</td>`);
});
return table;
}
});
<div id="title"></div>
<script src="/TrainingResourceCenter/O365Training/SiteAssets/roadmap.js?v=1"></script>
I want it to output the results from roadMapdisplay.
innerHTML is a DOM Element property, and not directly exposed by jQuery. To get it use html() instead.
Ref. http://api.jquery.com/html/
document.getElementById('title').innerHTML = $table.html();

How can I kill all my functions after execution?

I have a condition column == 1 and if this is the case, the function MakeCellsEditable and the function myCallbackFunction are initialized:
<script src="https://raw.githubusercontent.com/ejbeaty/CellEdit/master/js/dataTables.cellEdit.js"></script>
$(document).ready(function () {
var table = $('#myTable').DataTable();
$('#myTable tbody').on('mousedown', 'td', function () {
$('#myTable').data('column', table.cell(this).index().columnVisible);
});
if (column == 1) {
table.MakeCellsEditable({
"onUpdate": myCallbackFunction
});
}
});
function myCallbackFunction(updatedCell, updatedRow, oldValue) {
var array = updatedRow.data();
var id = array[0];
var column = $('#myTable').data('column');
console.log("The column is: " + column);
jQuery.ajax({
type: "POST",
url: "update.php",
data: {
updatedCell: updatedCell.data(),
id: id,
column: column,
},
cache: false
});
}
What I want to do is, after the functions are executed, I want to kill them. Because otherwise if I one time clicked column 1, then all my tables are editable (not only column 1).
I tried table.unbind(); or table.die(), but this didn't work out.
I tested at the end of the code:
function destroyTable() {
if ($.fn.DataTable.isDataTable('#myTable')) {
table.destroy();
table.MakeCellsEditable("destroy");
}
}
But it didn't work out
To answer the question in the headline: Yep:
function thiswilljustworkonce(){
alert("once");
this.thiswilljustworkonce=function(){};
}
thiswilljustworkonce();
thiswilljustworkonce();
Use columns option for CellEdit plugin to specify which column needs to be editable. There would be no need to remove event handler.
var table = $('#example').DataTable();
function myCallbackFunction (updatedCell, updatedRow, oldValue) {
console.log("The new value for the cell is: " + updatedCell.data());
console.log("The values for each cell in that row are: " + updatedRow.data());
}
table.MakeCellsEditable({
"columns": [0],
"onUpdate": myCallbackFunction,
"confirmationButton": true
});
See this example for code and demonstration.

Filter JSON object with Array of selected checkbox

How i can filter my JSON object with array.
FIDDLE
This is an sample of my json object and code, i want to filter final render HTML by selected checkbox.
Thanks for your help
function init(arr){
var li = '';
$.each(jsn, function (key, value) {
if (arr.length == 0) {
li += '<li>' + jsn[key].name + '</li>';
}else{
$(arr).each(function (i, v) {
// this section must be filter "pack's" but i can't writ correct query
li += '<li>' + jsn[key].name + '</li>';
});
};
$('#container').html(li);
})
}
var CheckArr = new Array();
init(CheckArr);
$('#btnFilter').click(function(){
var CheckArr = new Array();
$('input[type=checkbox]').each(function () {
if ($(this).is(':checked')) {
CheckArr.push($(this).attr('value'))
}
});
init(CheckArr);
First of all, you have to verify length of array outside of init function. (for case when function is called for first time).Then, you need to iterate your checkboxes array and search every item in your json array(called jsn) to verify condition you need.
Here is solution:
$(document).ready(function(){
var jsn = [
{
"name":"pack01",
"caplessthan100mb":"False",
"cap100to500mb":"True",
"cap500mbto2g":"False",
"cap2gto10g":"False"
},
{
"name":"pack02",
"caplessthan100mb":"True",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"False"
},
{
"name":"pack03",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"True"
},
{
"name":"pack04",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"True",
"cap2gto10g":"False"
},
{
"name":"pack05",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"True"
},
{
"name":"pack06",
"caplessthan100mb":"True",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"False"
},
{
"name":"pack07",
"caplessthan100mb":"False",
"cap100to500mb":"False",
"cap500mbto2g":"False",
"cap2gto10g":"True"
}
];
function init(arr){
var li = '';
if(arr.length==0)
{
$.each(jsn, function (key, value) {
li+= '<li>' + jsn[key].name + '</li>';
});
}
else{
$(arr).each(function (i, v) {
$.each(jsn, function (key, value) {
if(jsn[key][v]=="True")
li+= '<li>' + jsn[key].name + '</li>';
});
});
}
$('#container').html(li);
}
var CheckArr = new Array();
init(CheckArr);
$('#btnFilter').click(function(){
var CheckArr = new Array();
$('input[type=checkbox]').each(function () {
if ($(this).is(':checked')) {
CheckArr.push($(this).attr('value'))
}
});
init(CheckArr);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li><input type="checkbox" value="caplessthan100mb">caplessthan100mb</li>
<li><input type="checkbox" value="cap100to500mb">cap100to500mb</li>
<li><input type="checkbox" value="cap500mbto2g">cap500mbto2g</li>
<li><input type="checkbox" value="cap2gto10g">cap2gto10g</li>
<li><input type="button" id="btnFilter" value="Filter"></li>
</ul>
<br />
<ul id="container">
</ul>
There are quite a few things in your code that could use improvement so I've taken the liberty of largely rewriting it (see jsFiddle link below).
1) First thing is in your data (jsn) you are using "False" and "True" instead of false and true. That'll make it hard to write your filter condition because true != "True".
2) It's quite hard to debug your code because the variable names aren't very meaningful. I'd highly recommend putting some energy into improving your variable names especially when code isn't working.
For example:
packsData instead of jsn
checkedBoxes instead of arr
3) If you try to filter within the .each() below you'll run into trouble when it matches more than one filter condition (it'll be displayed more than once).
$(arr).each(function (i, v) {
// this section must be filter "pack's" but i can't writ correct query
li += '<li>' + jsn[key].name + '</li>';
});
Here is a working jsFiddle

Blaze.getData(el) returns null unless data property is accessed

I am trying to make a list of re-orderable items in Meteor. My items have a info.order property which I change on click events. Why does the example below work until I comment out if the line below // ! ...?
If I comment out that line I get the error Cannot read property '_id' of null when data._id is referenced in the event handler.
This is minimal Meteor javascript:
Widget = new Mongo.Collection('widget');
if (Meteor.isClient) {
function moveUp (mongo_id) {
var clicked = Widget.findOne({_id: mongo_id});
var above = Widget.findOne({'info.order': clicked.info.order - 1});
if (above) {
Widget.update({_id: clicked._id}, {$inc: {"info.order": -1}});
Widget.update({_id: above._id}, {$inc: {"info.order": 1}});
}
}
Template.widget.helpers({
// Get list of widget to display and sort by latest first.
widget: function(data){
return Widget.find({}, {sort: {'info.order': 1}});
},
display: function(mongo_id, info) {
var html = '<div>';
html += '<div>' + info.label + '</div>';
html += '<div>Up</div>';
// ! IF NEXT LINE IS COMMENTED-OUT data == null IN EVENT HANDLER
html += '<div>' + info.order + '</div>';
html += '</div>';
return html;
}
});
Template.widget.events({
'click .js-moveup': function(e, tpl){
e.preventDefault();
var data = Blaze.getData(e.currentTarget);
moveUp(data._id);
}
});
} // end is MeteorClient
With this template:
<head></head>
<body>
{{> widget}}
</body>
<template name="widget">
<div class="container">
<h1>Widgets</h1>
{{#each widget}}
{{{display _id info}}}
{{/each}}
</div>
</template>
And this seed data:
Meteor.startup(function () {
if (Widget.find().count() === 0) {
[{info :{label: "first", order: 1}},
{info: {label: "second", order: 2}},
{info: {label: "third", order: 3}}
].forEach(function(w){
Widget.insert(w);
});
}
});
I've got an idea what's going on...
Meteor must compare the output of display() to it's previous value and only evaluate update the DOM if it has changed (or something similar). If I don't print out info.order the HTML of each widget is unchanged.
I tested this by replacing info.order with new Date() to add varying content that didn't reference the model and, sure enough, the widgets more as expected.
So, my take home message is that if you return raw HTML from display Meteor will try to do the write thing but won't always get it right.

Suggest any Good mustache document

Suggest me any good mustache doc. Also i want to know in a mushtach loop how do i get the count or the loop no. I mean how can i do a for loop in mustache.
In the below code i wish to change the id in every loop
<script src="http://github.com/janl/mustache.js/raw/master/mustache.js"></script>
<script>
var data, template, html;
data = {
name : "Some Tuts+ Sites",
big: ["Nettuts+", "Psdtuts+", "Mobiletuts+"],
url : function () {
return function (text, render) {
text = render(text);
var url = text.trim().toLowerCase().split('tuts+')[0] + '.tutsplus.com';
return '' + text + '';
}
}
};
template = '<h1> {{name}} </h1><ul> {{#big}}<li id="no"> {{#url}} {{.}} {{/url}} </li> {{/big}} </ul>';
html = Mustache.to_html(template, data);
document.write(html)
</script>
<body></body>
You can't get at the array index in Mustache, Mustache is deliberately simple and wants you to do all the work when you set up your data.
However, you can tweak your data to include the indices:
data = {
//...
big: [
{ i: 0, v: "Nettuts+" },
{ i: 1, v: "Psdtuts+" },
{ i: 2, v: "Mobiletuts+" }
],
//...
};
and then adjust your template to use {{i}} in the id attributes and {{v}} instead of {{.}} for the text:
template = '<h1> {{name}} </h1><ul> {{#big}}<li id="no-{{i}}"> {{#url}} {{v}} {{/url}} </li> {{/big}} </ul>';
And as an aside, you probably want to include a scheme in your url:
url : function () {
return function (text, render) {
text = render(text);
var url = text.trim().toLowerCase().split('tuts+')[0] + '.tutsplus.com';
return '' + text + '';
//---------------^^^^^^^
}
}
Demo: http://jsfiddle.net/ambiguous/SFXGG/
Expanding on #mu's answer, you could also keep an index in the data object and have the template refer to it and the function increment it. So you wouldn't need to add i to each item.
see demo : http://jsfiddle.net/5vsZ2/

Categories