Trigger function from within formatter? (responsiveLayout: collapse > toggleList) - javascript

Is there a way to trigger a function from within a rowFormatter? I'm using the responsiveLayout: "collapse"-option, and I really like it.
However, I would like to trigger the toggleList function (or what's it's called.... 1 from '19)
I would like to not go the .click() way, so I created my own (rip-off) solution within the rowClick:
let isOpen = row._row.modules.responsiveLayout.open;
var collapseEl = row._row.element.querySelector('div.tabulator-responsive-collapse');
if (!(isOpen)) {
collapseEl.classList.add("open");
if (collapseEl) {
collapseEl.style.display = '';
}
} else {
collapseEl.classList.remove("open");
if (collapseEl) {
collapseEl.style.display = 'none';
}
}
row._row.modules.responsiveLayout.open = !(isOpen);
But... There must be a good way to trigger toggleList(), instead of writing a rip-off function, which doing the same thing...
I've tried to look through the values and functions in row._row, with no luck. I'm 99.7% sure that I missed this part in the documentation........ But I've really tried to search the best I could.
TL;DR: I would like to trigger the toggleList() function defined within formatter, in my rowClick() event-function. Is that possible?

There is no toggleList function built into Tabulator.
In the example you reference there it is simply a function called toggleList that is defined inside the row formatter and triggered when an element added by the row formatted is clicked.
Because the toggleClick function is defined inside the row formatter its scope is limited to that formatter function so it cannot be accessed from outside it.
one way to get around this would be to assign the function to a property on the row data object then you could access it from else where in the table.
So if we take the example you provided a link to and at the top of the customResponsiveCollapseFormatter function add the following:
var data = cell.getData(); //retrieve the row data object
Yhen where we define the toggleList function, instead of the simple function definition we can assign it to a property on the data object, lets call it collapseToggle, we will also tweak it so it dosnt need the isOpen property passed in and insted flips the state of the open variable itself, that way it can be called from anywhere outside the formatter without knowledge of the current state:
data.collapseToggle = function toggleList(){
open = !open;
Then in our cellClick function we can check to see if the collapseToggle property is defined on the row data and then call it:
cellClick:function(e, cell){
var data = cell.getData();
if(data.collapseToggle){
data.collapseToggle();
}
}

Related

Json data from table in an onclick function show in seperate div

I'm trying to get data used in my table to be used in a div when I click on the table. The thing is, there are multiple tables in my script according to the data of my JSON. So my JSON consists of object that consists of object. For example:
My table(s) are rendered like this:
data.forEach(function(somedata){
return '<table><tr><td>'+somedata.something+'</td></tr></table>';
});
Now I've tried to get the onclick to work in this case but I cant seem to figure out how. I'd like to not use specific ID's rendered in the foreach like:
var i=0;
data.forEach(function(somedata){
i++;
return '<table id="'.id.'"><tr><td>'+somedata.something+'</td></tr></table>';
});
the variable somedata consists of an object so I cant just make an onclick in the html code of the table either and send the data in it.
So somedata would look something like this but json encoded:
somedata{
[0]=>array(
'something'=>'test',
'theobject'=>array(...)
),
[1]=>array(etc...)
}
Now what I want is to get the data from theobject in a seperate div as soon as I click on the table that belongs to the right somedata.
I've been thinking of making a jquery on click for this but then I would need specific ID's in the table(if that's the only possible solution then I'd take it). Cant I do something with this or something? Or send the data at the same time it's being rendered cause in my code I can at the moment of course reach to somedata.theobject
I think I'm thinking a bit too difficult about this. Am I?
You can pass this in onclick function like
return '<table onclick=makeObject(this)><tr><td>'+somedata.something+'</td></tr></table>';
And then use the function to get the data
function makeObject(that){
var tbl = $(that).find('tr').map(function() {
return $(this).find('td').map(function() {
return $(this).html();
}).get();
}).get();
}
There are a few ways to go about this. Rather than using the forEach function we can use the jQuery.map function, since you've indicated that you're open to using jQuery :-)
var $els = $.map(data, function(somedata, i){
var $el = $('<table><tr><td>'+somedata.something+'</td></tr></table>')
.click(function(e) {
populateDivWithData(somedata.theobject);
});
return $el;
});
The call to .click inside each will create a separate click handler for each item in data; each click handler then has access to the relevant theobject value.
EDIT: Thanks #Loko for the reminder about the .forEach built-in

How to make variable accessible within jQuery .each() function?

This is and example of a frequent dilemma: how to make markup accessible inide this .each()?
I'm more interested in learning how to access outer variables from within a closure than I am in this specific issue. I could fix this problem by assigning markup from inside the each function, but I'd rather learn a more elegant way to handle this kind of problem.
// hide form & display markup
function assessmentResults(){
// get assessment responses
var markup = parseForm();
// show assessment results to user
$('#cps-assess-form fieldset').each( function() {
var q = $(this).find('.fieldset-wrapper');
var i = 0;
// hide form questions
q.slideUp();
// insert markup
$('<div>'+markup[i]+'</div>').insertAfter(q);
i++;
});
}
Read the docs, it already has an index!
.each( function(index, Element) )
No need for i
$('#cps-assess-form fieldset').each( function(index) {
var q = $(this).find('.fieldset-wrapper').slideUp();
$('<div/>').html(markup[index]).insertAfter(q);
});
The reason why yours is failing is the i is inside of the function so it is reset every iteration. You would need to move it outside of the function for it to work.

Javascript, passing a variable into a click event?

I really can't figure out how I would do this. It's more of a concept question than a code question so I'll just post an example:
object = $('#div');
function doSomething(object) {
//iterates through a list and creates a UL with items in corresponding to that list.
$(body).append("<li id='clickme'>Hello world</li>");
}
function createModal(object) {
//creates modal dialogue.
doSomething(object);
//more stuff
}
$('#clickme').live("click", function() {
//I need access to object (not the object declared at first,
//the object passed into doSomething) here.
});
Any ideas how I would do such a thing? doSomething would create a set of LIs and have a parameter passed into it. When those LIs the function creates are clicked, they need to interact with the parameter that's passed into doSomething. Is there a way to bind them or something?
Sorry if I didn't make any sense.
You can use jquery data function to associate data to your DOM elements. You then can read those data when handling events.
An alternate way, generally not recommended but useful when you build your html in one big pass and don't have an easy access to the DOM elements, and only have strings (or keys), is to add an attribute and retrieve it later using jquery's attr function. Whenever possible I recommend you to use the data function though.
Store the reference explicitly:
function doSomething(object) {
//iterates through a list and creates a UL with items in corresponding to that list.
$(body).append(
$("<li/>", { id: 'clickme', text: 'Hello world',})
.data('object', object)
);
}
Then the event handler can retrieve the reference:
$('#clickme').live("click", function() {
var object = $(this).data('object');
// ...
});
Also .live() is deprecated:
$('body').on('click', '#clickme', function() {
is the hip new way to bind delegated event handlers.
object = $('#div');
function doSomething(object) {
$(body).append("<li id='clickme'>Hello world</li>");
$('#clickme').click(function(evt) {
// Here you have access to `object`
});
}
function createModal(object) {
//creates modal dialogue.
doSomething(object);
//more stuff
}
This might not be enough. If you are creating multiple links rather than just the single one with id clickme you might have to find a different selector to use when you attach the click-handler. But if you nest the function that way, you have access to the parameter object that was used when the click-handler was created.
Another option would be to declare and attach the handler in a location where the parameter would be in scope, through closures (not tested):
function doSomething(object) {
$(body).append("<li id='clickme'>Hello world</li>").click(function() {
//object is accessible here
});
}

Returning a value to another function

I am new to jQuery. I have created a form where I hide some fields. I have created a function on the click of a button field. Here in this function definition I unhide the hidden fields one being my text field and another a button. I code that I use is:
finishOrder: function() {
document.getElementById("create-pwd").style.display = "block"
document.getElementById("finish-ok").style.display = "block" // this is my another button
// do further processing
},
Now on the click of another button (please see the comment "this is my another button") I call another function like this:
FinishcheckPassword: function() {
var pas = document.getElementById("pos-password")
var user = new db.web.Model("res.users").get_func("read")(this.session.uid, ['password']).pipe(function(result) {
if(pas.value == result.password){
return true
});
},
After the if condition returns true value, I want to the control to be transferred to the first function where I can do further processing. Is it possible, if yes how can this be achieved? Any help will be appreciated.
Sure, something like this:
$('#finish-ok').click(function(){
if(FinishcheckPassword()){
finishOrder();
}
}
Of course, this is probably not exactly the right code for you. The fact that you are assigning all your functions with : rather than = suggests that they are inside of some larger object. Therefore, they'd have to be called like myObject.finishOrder(). But the general approach of what I wrote above will work.
As a couple side notes, you have tagged the question with jQuery and refer to it in your post, but there isn't actually a single line of jQuery in your code.

The Function Works But Reports this.refresh() is not a function

I get this.refresh() is not a function in the error log every time I use this function but it works fine.
Also, when I click on this function for the first time, this.value=undefined. When I click the function again in this form and every other form, the value populates just fine with the previous value.
What could I be doing wrong?
How do I write this function more efficiently?
I still don't quite understand how to use this.value to capture and store a value within an array.
function askGender(x) {
response = "<select class=widgetstyle onClick=_setGender(this.value)><option value=Female>Female<option value=Male>Male</select>";
characters[x].setGender(response);
if (this.gender != 0) {
response = this.gender;
this.gender = 0;
characters[x].setGender(response);
}
}
function _setGender(x) {
this.gender = x;
this.refresh();
}
response = "<select class=widgetstyle onClick=_setGender(this.value)><option value=Female>Female<option value=Male>Male</select>";
look at your response. You set the gender in the click handler. Your misunderstanding on how this works.
this in askGender refers to your character object. When the onClick handler get's called this will refer to the DOM object in your setGender method.
For the record .refresh is a method of his Character object.
The entire code is large and requires thorough debugging. It looks like your editing open source code and trying to use it in a way it was not designed to be used.

Categories