Link to home
Start Free TrialLog in
Avatar of -Dman100-
-Dman100-Flag for United States of America

asked on

Need help - variable does not get set correctly

I am trying to use the following script that is on GITHUB: click here

I'm debugging the code and it shows that I enter the function, but the j$boxes variable is empty. In the console, it shows the length is empty. I'm new to jquery and still struggling with learning how to properly select elements on the page and properly debug using the browser tools.

Here is  my code with my debug statements. I'm also attaching an image of the output from the debug console.
j$ = jQuery.noConflict();

j$(document).ready(function() {
	
	if(j$) {
		//alert('Jquery loaded successfully...');
	}
	j$('input[id$=btnSearch]').click(function(){
		console.log('******************** search button has been clicked');
		j$('input[type="checkbox"]').shiftSelectable();
	});		
});

j$.fn.shiftSelectable = function() {
console.log('*********************** we are inside the shiftSelectable function');
    var lastChecked,
        j$boxes = this;
console.log(j$boxes);
console.table(j$boxes);
    j$boxes.click(function(evt) {
	console.log('************************** we are inside the boxes click event handler');
        if(!lastChecked) {
            lastChecked = this;
            return;
        }

        if(evt.shiftKey) {
            var start = j$boxes.index(this),
                end = j$boxes.index(lastChecked);
            j$boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
                .attr('checked', lastChecked.checked)
                .trigger('change');
        }

        lastChecked = this;
    });
};

Open in new window

7-18-2018-9-44-34-AM.jpg
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

My guess would be that you don't have any checkboxes on your page.
Avatar of -Dman100-

ASKER

The checkboxes are definitely on the page. When the page first loads, there are no checkboxes, the user enters a search term using an input and clicks the search button, the page does a partial page post back and returns the results in a table with a checkbox for each row. Is the partial page post back have some kind of impact?
Here is an image of the page (see attached)
7-18-2018-10-16-08-AM.jpg
We do you let us guess what's happing? Why not posting a concise and complete example???

Cause when I craft one, it works as intended..

<!DOCTYPE html>
<html>

<head>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script>
        j$ = jQuery.noConflict();
        j$.fn.shiftSelectable = function() {
            var lastChecked,
            $boxes = this;
            $boxes.click(function(evt) {
                if(!lastChecked) {
                    lastChecked = this;
                    return;
                }

                if(evt.shiftKey) {
                    var start = $boxes.index(this),
                        end = $boxes.index(lastChecked);
                    $boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
                        .attr('checked', lastChecked.checked)
                        .trigger('change');
                }

                lastChecked = this;
            });
        };

        j$(document).ready(function() {
            j$('input[type="checkbox"]').shiftSelectable();
        });
    </script>
</head>

<body>
    <input type="checkbox" name="c1">
    <input type="checkbox" name="c2">
    <input type="text" name="t1">
    <input type="checkbox" name="c3">
    <input type="checkbox" name="c4">
</body>
</html>

Open in new window

It all depends on exactly when your checkboxes are available to the DOM and when you're calling your plugin. All I know is that if you're getting the results you're getting, it's because your code can't see any checkboxes in the DOM. As ste5an says, you've only shown us a small part of your code, so we're left guessing. If you look at this fiddle, you'll see it works as expected - https://jsfiddle.net/ChrisStanyon/htqmgzk2/

There's clearly more going on with your code than we're aware of.
Addition - you say that a user clicks on a search button a loads a partial - the code you've shown us does no such thing. It simply calls your plugin(). Where in your code are you loading the partial ??
I'm not trying to have anyone guess. What would you like to see? The page includes a ton of code. I was trying to be concise and show what I was trying to implement. If I posted all the page source, then I would likely get a message stating I'm posting too much code. So, please let me know what you would like to see and I'll do my best to provide it for you. Thanks.
Chris, thanks for your help as always. What I meant by partial page post back is that on the platform I'm developing on which is Salesforce, there is controls within visualforce that works as a partial page post back when you use a reRender attribute on the button component and point to the section of the page that you want to reRender instead of reRendering the entire page. If that helps explain.
SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
When the page first loads, there are no checkboxes, the user enters a search term using an input and clicks the search button, the page does a partial page post back and returns the results in a table with a checkbox for each row

Is the partial page post back have some kind of impact?
Yes, your plugin don't work with dynamic fields :
Try this :

j$ = jQuery.noConflict();

j$(document).ready(function() {
        var runAfterEveryPostback  = function() {
           	j$('input[id$=btnSearch]').click(function(){
           	console.log('******************** search button has been clicked');
           	j$('input[type="checkbox"]').shiftSelectable();
	});
	Sys.WebForms.PageRequestManager.getInstance().add_endRequest(runAfterEveryPostback);
});

j$.fn.shiftSelectable = function() {
console.log('*********************** we are inside the shiftSelectable function');
    var lastChecked,
        j$boxes = this;
console.log(j$boxes);
console.table(j$boxes);
    j$boxes.click(function(evt) {
	console.log('************************** we are inside the boxes click event handler');
        if(!lastChecked) {
            lastChecked = this;
            return;
        }

        if(evt.shiftKey) {
            var start = j$boxes.index(this),
                end = j$boxes.index(lastChecked);
            j$boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
                .attr('checked', lastChecked.checked)
                .trigger('change');
        }

        lastChecked = this;
    });
};

Open in new window

I forgot a bracket in previous post :
        j$ = jQuery.noConflict();

        j$(document).ready(function() {
            var runAfterEveryPostback  = function() {
                j$('input[id$=btnSearch]').click(function () {
                    console.log('******************** search button has been clicked');
                    j$('input[type="checkbox"]').shiftSelectable();
                });
            }
            Sys.WebForms.PageRequestManager.getInstance().add_endRequest(runAfterEveryPostback);
        });

        j$.fn.shiftSelectable = function() {
            console.log('*********************** we are inside the shiftSelectable function');
            var lastChecked,
                j$boxes = this;
            console.log(j$boxes);
            console.table(j$boxes);
            j$boxes.click(function(evt) {
                console.log('************************** we are inside the boxes click event handler');
                if(!lastChecked) {
                    lastChecked = this;
                    return;
                }

                if(evt.shiftKey) {
                    var start = j$boxes.index(this),
                        end = j$boxes.index(lastChecked);
                    j$boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
                        .attr('checked', lastChecked.checked)
                        .trigger('change');
                }

                lastChecked = this;
            });
        };

Open in new window

Thank you leakim971, Chris and Ste5an, I implemented the updated code, but it is not recognizing 'Sys' and errors that it is undefined. I'm assuming this is because Visualforce does not recognize the Sys.Webforms namespace. The solution you provided makes sense and I'm looking into details about dynamic fields using visualforce.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
it look like the equivelent in visualforce is to use the "oncomplete" attribute for the action loading this partial page :
so using first solution :
<apex:commandButton ... oncomplete="runAfterEveryPostback();"

Open in new window

Thanks for all your help! The function that accepts the selector as the parameter works. I'm testing the other option using oncomplete event in the command button, but nothing happens. I'm not getting any errors, but nothing fires.

If I understand the function, you are passing in the type of event "click",  the selector, and the event itself that can be referenced using the "this" keyword. It definitely selects all the checkboxes using shift + click. Once the checkboxes get selected, I have to pass those updated rows to the selected list property so I can process them on the back end.


Thanks again for all your help! This was extremely informative and helpful!
Great examples and help!! Thank you!!
Just a quick follow-up...I was able to get it all working successfully on my page. The shift+click works properly selecting and deselecting and I was able to call my action method from within the jquery function so that it could pass the selected rows back to the controller for processing. Thanks again for the help!!

Regards