Jump to content

jQuery Help


bsmither

Recommended Posts

Working on the project where an AJAX query is made to CubeCart.

 

I'm not skilled enough to figure out the jQuery. Here's what I have so far. Do not assume any of it is syntactically correct::

if ($('div#stock_level_check').exists())
{ // A place to put ajax return? This skin modified!
    var indicator = $('form.addForm input[name="check_stock"]'); // a new button on the form
    var selectors = $('form.addForm label.return select'); // collection of option selectors
    selectors.each(function()
    { // check if any selector is not selected and if so...
        if($(this).option.value == '') do not do ajax;
        var ois = selectors.serialize(); // otherwise, contains assign_ids
            $.ajax({
                url: action + '_g=rm&type=plugins&module=ajaxoptions&cmd=call',
                type: 'POST',
                cache: false,
                data: ois,
                complete: function(returned)
                {
                    if (returned.responseText)
                    { // stock level
                        indicator.val().replaceWith(returned.responseText);
                        // for button[name="check_stock"] replace class="button_white" with "button_green" }
                    else
                    { // out of stock or no stock
                        indicator.val().replaceWith("Sorry");
                        // for button[name="check_stock"] replace class="button_white" with "button_red" }
                }
            });
    });
};

 

 

 

Link to comment
Share on other sites

This is exactly the kind of thing I was envisaging. I'm a bit hungover today though so my brain power is limited. 

 

I expect this is the way to go entirely but I'm not sure having a check stock button would be so nice. Maybe that just for phase one dev.. I would have thought that there should be a listener that triggers this once a drop down or all drop downs have been selected to perform the check.

Link to comment
Share on other sites

This is exactly the kind of thing I was envisaging. I'm a bit hungover today though so my brain power is limited.

The beer at the pub last night was obviously good !

I expect this is the way to go entirely but I'm not sure having a check stock button would be so nice. Maybe that just for phase one dev.. I would have thought that there should be a listener that triggers this once a drop down or all drop downs have been selected to perform the check.

I think the best way would be to trigger a lookup after any change to a drop down and only display option combinations that are in stock (if hide out of stock is selected)

Link to comment
Share on other sites

Triggering on change will be in there, just don't know how to do that specifically.

$( "select" )
.change(function() {
var str = "";
$( "select option:selected" ).each(function() {
str += $( this ).text() + " ";
});
$( "div" ).text( str );
})
.trigger( "change" );

It will be similar to the above (taken from the jQuery API doc site), but needs to collect the selected options' values.

 

So, this may be useful:

$( selectors ).val() || [ ];

Link to comment
Share on other sites

I have managed to get the code to not cause any errors. But there is still no response (see alert() statements) when selectors are changed.

 /* Custom javascript to ajax query for
 * stock level for the selected option
 * combo.
 */

jQuery(document).ready(function() {

/* From W3C Schools, and it works
$(document).ready(
function(){
  var selectors = $('form select.sel');
  selectors.change(
    function(){
      selectors.each(
        function(){
          alert($(this).val());
        }
      )
    }
  );
});
*/
    if ( $('div#stock_level_check').exists()
      && $('form.addForm input[name="add"]').exists() )
    { alert("triggers exist");
        var indicator = $('form.addForm input[name="check_stock"]');
        var add = $('form.addForm input[name="add"]');
        var selectors = $('form.addForm label.return select');
        var goajax = false;
   
        $(selectors).change(
            function()
            { alert("something changed");
                goajax = true;
                $(selectors).each(
                    function()
                    {
                        if ( !$(this).val().exists() )
                        {
                            goajax = false;
                            alert($(this).val());
                        }
                        else
                        {
                            alert("not" + $(this).val());
                        }
                    }
                )
            }
        );
   
        if (goajax)
        {
            var ois = $('form.addForm label.return select').serialize(); // contains assign_ids
            $.ajax(
                {
                    url: action + '_g=rm&type=plugins&module=ajaxoptions&cmd=call',
                    type: 'POST',
                    cache: false,
                    data: ois,
                    complete: function(returned)
                    {
                        if (returned.responseText == false || returned.responseText == 0)
                        {
                            alert(returned.responseText);
                        }
                        else
                        {
                            alert(returned.responseText);
                        }
                    }
                }
            );
        }
    }
   
/* From Estelle's mod
    var sl_elements = [];
    var index = 0;
    sl_elements[index++] = document.getElementsByName('productOptions[]');
    for (var i=0; i<sl_validOptionIds.length; i++) {
      option_id = sl_validOptionIds;
      sl_elements[index++] = document.getElementsByName('productOptions_'+option_id);
      sl_elements[index++] = document.getElementsByName('productOptions_'+option_id+'[]');
      sl_elements[index++] = document.getElementsByName('productOptions['+option_id+']');
    }
*/

});
Link to comment
Share on other sites

Hey Brian,
 
I'd recommend using the "console.log" instead as if you would var_dump in PHP to debug. If you then look at the console section of your browser debug bar it should show the data. If there are page redirect involved be sure to set the log to preserve. There are a number of different ways to take the select change event but with the change method you are using I think you need to use.

selectors.on('change', function() {
...
});

It may also be worth experimenting with other events like .blur() or .focusout()

Link to comment
Share on other sites

The way I'd generally do it is like this:

	var selectors = jQuery('form.addForm label.return select');
	function ccOptionAjax(){
		var assignArr = new Array();
		var arrCount = 0;
		var goAjax = true;
		
		jQuery(selectors).each(function(){
			var oSelected = jQuery(this).find("option:selected");
			if(oSelected.length > 0 && oSelected.val() > 0){
				assignArr[arrCount++] = oSelected.val();
			} else {
				goAjax = false;
			}
		});
		
		if(goAjax){
			
		}
	}
	
	jQuery(document).ready(function(e){
		jQuery(selectors).each(function(){
			jQuery(this).change(function(){
				ccOptionAjax();
			});
		});
	});

I generally use jQuery explicitly over $ as a matter of course, just for the rare occasions where a store ends up being smushed together with another system which is running prototype, otherwise they kinda hate each other.

 

Running each before change (or blur or any other event) is more a personal preference/paranoia thing I think, I used to have a few scripts just refuse to run the other way round, but I suspect this was more due to very old versions of jQuery or other similar bugs, I don't think there's any especial advantage to doing so.

 

Calling a function instead of putting the code inside the change is a much better thing though as far as I'm aware, as javascript ends up creating a full function for each event trigger. Ideally you want to minimise the size of those to reduce overhead, so having them just reference a single function can help with that.

 

Similarly not sure if you still need to have the functions outside of the document.ready, but I also had problems with that in the past, so I put them out in the open as a matter of habit these days.. pretty much the same with running a find of option:selected.. I've found running val() on the select way too flakey over the years, so I end up just sticking with someone I know works on those situations

 

I'd also suggest sending over the array in JSON via the ajax, it's just a little nicer as you can then just json_decode it on the php side and get an array, rather than fiddle with unsafeing data and exploding

 

Seconding the use of console.log though, it's a much handier function than alert, and a lot better for when you're chucking out lots of debug data

Link to comment
Share on other sites

I made a few adjustments after trying this verbatim (because verbatim didn't work). The following still doesn't work.

 

I get the Document ready notice and the Triggers exist notice in the console. There are no other notices.

/* Custom javascript to ajax query for
 * stock level for the selected option
 * combo.
 */

    function ccOptionAjax(){ console.log("Doing ccOptionAjax");
        var assignArr = new Array();
        var arrCount = 0;
        var goAjax = true;
        
        $(selectors).each(function(){
            var oSelected = $(this).find("option:selected");
            if(oSelected.length > 0 && oSelected.val() > 0){
                assignArr[arrCount++] = oSelected.val();
            } else {
                goAjax = false;
            }
        });
        
        if(goAjax){
            console.log("Did the goAjax");
        }
    }
    
    jQuery(document).ready(function(e){ console.log("Document ready.");
        if ( $('div#stock_level_check').exists()
          && $('form.addForm input[name="add"]').exists() )
        { console.log("Triggers exist");
            var selectors = $('form.addForm label.return select');
/*
            $(selectors).each(function(){ console.log("Working on a selector.");
                $(this).change(function(){ console.log("Something changed.");
                    ccOptionAjax();
                });
            });
*/
            $(selectors).on('change', function() {  console.log("Something changed.");
                ccOptionAjax();
            });

        }
    });
Link to comment
Share on other sites

Bah, do apologise, I misread a bit of the original code and it's wonky due to that

 

I'd managed to read where you were originally setting up the selectors variable, to be a selector string, not actually setting it to the elements. You probably want it to be

 

var selectors = 'form.addForm label.return select';

 

To use it in the way we are doing

 

Also, it'll need to be outside of document ready, otherwise it won't necessarily be in scope for the function

 

Once you've got the triggers output, try doing:

 

console.log(jQuery(selectors));

 

console.log is pretty swish, it'll happily output entire elements or arrays for you to look through and confirm they're getting picked up

Link to comment
Share on other sites

Don't assume I know what I'm doing.

 

I did have this:

selectors.each()

selectors.on()

 

but didn't work, so I tried this:

$(selectors).each()

$(selectors).on()

 

and now I see what that difference implies.

 

I will go back to using the variable that had a jQuery object assigned to it as I prefer that style. I also put

var selectors = $('form.addForm label.return select');

outside of document ready. The console log does show I have an object in selectors. It has a .length of 0.

 

Still not getting any change notice in the console log.

Link to comment
Share on other sites

Well, it stands to reason that the CSS selector string will be very specific to the skin. (Which is why I am putting this javascript script into it's own file in the skin's /js/ folder.)

 

So, I will try:

form.addForm label.return~span>select

 

SUCCESS!

Link to comment
Share on other sites

Ok, all is functioning -- as far as it goes.

 

The relevant options must all be members of the Options Matrix, as that is where stock levels are recorded.

 

I now need to test situations where:

* one or more select options that is displayed is not part of the Matrix

* other situations not yet realized

 

Technically, I think the label.return is not required as it's only purpose I can see is CSS styling. Then I probably won't need span either. But I have to be careful to select only select[name^="productOptions"].

Link to comment
Share on other sites

I've got this all packaged up. Instructions written. It's version 1.0b1.

 

I need a fellow coder who:

  • IMPORTANT! Has the time to see how it reacts under various situations. This means someone not otherwise heavily involved in customer support issues, or going on vacation, or studying for college exams, etc.
  • Has an established Options Matrix table, or knows how to add such options so as to get one established.
  • Has a development installation so that this won't break anyone's livelihood.

I put the package at http://www.cubecartforums.org/index.php?showtopic=19100

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...