function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
JimmyBeWhiteJimmyBeWhite 

Apex:repeat w/ jQuery

I'm developing a page with a bit of jQuery and I'm having trouble with having trouble with jQuery sliders in a repeat. I don't think i'm traversing the DOM correctly.

 

Below is the visualforce code, the red text has the div, which is where the slider is rendered, and the inputText is where the value is to be shown.

 

 

<table>
	<tr>
          <td>
             Weighting for "{!assignmentToCreate.Name}"
          </td>
          <td>
          <div class ="weightSlider"></div>
          <input value="{!assignmentToCreate.Weighting_Value__c}" type="text"/>
          </td>
        </tr>
        <apex:repeat value="{!standardConfigs}" var="sta">
          <tr>
            <td>
               Weighting for "{!sta.Standard__c}"
            </td>
            <td>
              <div class ="weightStandardSlider"></div>
              <input value="{!sta.Default_Weighting__c}" type="text"/>
             </td>
           </tr>
         </apex:repeat>
 </table>

 Here's the javascript

function popUpWeights() {
        j$( "div.weightSlider" ).slider({
                value:1,
                min: 1,
                max: 10,
                slide: function( event, ui ) {
                    j$( "div.weightSlider" ).next().val(ui.value );
                }
            });
        j$( "div.weightStandardSlider" ).slider({
                value:1,
                min: 1,
                max: 10,
                slide: function( event, ui ) {
                    j$( "div.weightStandardSlider" ).next("input").val(ui.value );
                }
            });

        j$( "#weighting" ).dialog({modal: true});
        
    }

 The red text is where the code for the sliders within the repeat, the slider code above it works fine because it is not in the repeat. The blue text is what I think is wrong. The sliders all render but moving any one of them changes the value of the inputText field for ALL of them. 
Can I index the repeat and put the red javascript code in a for loop or something? I've been stuck on this for far too long...

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
JimmyBeWhiteJimmyBeWhite

Thank you so much for the help. The example code helped a lot.

 

After a few more frustrating hours I realized that i was attempting to use the ID on an object that had yet to be inserted. Luckily the object is a junction object so by using the ids of the two objects it is joining, i was able to create a unique id. The other issue I ran into was that the data wasn't binding, so I just changed <input> to <apex:inputField> - worked like a charm.

 

Below is the working code

Visualforce:

 

<table>
    <tr>
        <td>
            Weighting for "{!assignmentToCreate.Name}"
        </td>
        <td>
            <div class ="weightSlider"></div>
            <apex:inputField value="{!assignmentToCreate.Weighting_Value__c}"/>
        </td>
    </tr>
    <apex:repeat value="{!standardConfigs}" var="sta">
        <tr>
            <td>
                Weighting for "{!sta.id}"
            </td>
            <td>
                <div id ="{!sta.Section__c}{!sta.Standard__c}"></div>
                <apex:inputField value="{!sta.Default_Weighting__c}"/>
                
            </td>
        </tr>
    </apex:repeat>
</table>

 Javascript&colon;

 

<apex:outputPanel id="sliderWeights">
		<script>  
		var j$ = jQuery.noConflict();  
		
		 function popUpWeights() {//create sliders and put them in a pop up for the weights
		     j$( "div.weightSlider" ).slider({
		             min: 1, //these values need to be updated so they are dynamic
		             max: 10,
		             slide: function( event, ui ) {
		                 j$( "div.weightSlider" ).next().val(ui.value );
		             }
		         });
		
		     <apex:repeat value="{!standardConfigs}" var="sta">
		      j$( "#" + '{!sta.Section__c}' + '{!sta.Standard__c}' ).slider({
		              value: '{!sta.Default_weighting__c}',
		              min: 1,
		              max: 10,
		              slide: function( event, ui ) {
		                  j$( "#" + '{!sta.Section__c}' + 				'{!sta.Standard__c}').next("input").val(ui.value );
		              }
		          });
		         </apex:repeat>
		     j$( "#weighting" ).dialog({modal: true});
		 }
	 </script>
	</apex:outputPanel>

 Thanks again joshbirk!

 

 

All Answers

joshbirkjoshbirk

I think it is because you aren't giving it any unique identification, so jQuery is calling the slide function - which will trigger on anything that reaches that CSS selector.

 

You might be able to give the div a unique ID based on info within your repeater, and then either place the constructor within the row of the repeater, or maintain that list of ID's in a place that you could put it normally in document.onready.

 

In short though, instead of:

j$( "div.weightStandardSlider" )

You need something like:

j$( "#UniqueDivId" )
JimmyBeWhiteJimmyBeWhite

Thanks for the reply!

 

I understand that I need a unique id, but I don't know how to refer to it in the javascript.

 

if I put

 

<div id="{!sta.id}"></div>
<input value="{!sta.Default_Weighting__c}" type="text"/>

 What would i put for j$("#uniqueDivId)? can I wrap the slider jquery stuff in a for loop and somehow refer to it's integer variable? like
j$("#" + referredList(i).id)  or something? 

 

joshbirkjoshbirk

I think you could split the id list out into it's List var, and then setup a repeater within your jQuery onReady which iterated through that like you have above.  As long as the List<ID> matches the ids of your recordset, I think it should work.

 

I can cobble some sample code tonight if it would help.

JimmyBeWhiteJimmyBeWhite

some example code would be amazing. I'm not using the document.ready function because the number of sliders needed isn't set right away. Its based on a list built from selected objects. So I just call it via 'oncomplete="javascript();"'  from a commandbutton. what do you mean by split the id list out into its List var?

 

Thanks again for the help

joshbirkjoshbirk

Yeah, when I tried it out in code, it worked different than how I was describing.  I think what you need is to move the jQuery construction to an outputpanel you rerender when you hits your oncomplete.  In the test code I put together, I used an onChange to call an actionFunction, which called the new SOQL query, which then called "resetSliders" with the oncomplete, so it should be pretty similar to rerendering what I've got as "campaignTable" here.

 

 

<apex:outputpanel id="campaignTable">
<script>
	function resetSliders() {
		<apex:repeat value="{!opportunities}" var="opp">
		j$( "div#opp{!opp.Id}" ).slider({
                value:{!opp.Amount},
                min: 1,
                max: 10000000,
                step: 1000,
                slide: function( event, ui ) {
                    j$( "div#opp{!opp.Id}" ).next("input").val(ui.value );
                }
            });
		</apex:repeat>
	}
</script>
<table>
<apex:repeat value="{!opportunities}" var="opp">
 <tr>
 	<td>{!opp.Name}</td>
 	<td>{!opp.Amount}</td>
 	<td><div id="opp{!opp.Id}"></div>
        <input value="{!opp.Amount}" type="text"/></td>
 </tr>	
</apex:repeat>
</table>
</apex:outputpanel>

 HTH

 

JimmyBeWhiteJimmyBeWhite

Thank you so much for the help. The example code helped a lot.

 

After a few more frustrating hours I realized that i was attempting to use the ID on an object that had yet to be inserted. Luckily the object is a junction object so by using the ids of the two objects it is joining, i was able to create a unique id. The other issue I ran into was that the data wasn't binding, so I just changed <input> to <apex:inputField> - worked like a charm.

 

Below is the working code

Visualforce:

 

<table>
    <tr>
        <td>
            Weighting for "{!assignmentToCreate.Name}"
        </td>
        <td>
            <div class ="weightSlider"></div>
            <apex:inputField value="{!assignmentToCreate.Weighting_Value__c}"/>
        </td>
    </tr>
    <apex:repeat value="{!standardConfigs}" var="sta">
        <tr>
            <td>
                Weighting for "{!sta.id}"
            </td>
            <td>
                <div id ="{!sta.Section__c}{!sta.Standard__c}"></div>
                <apex:inputField value="{!sta.Default_Weighting__c}"/>
                
            </td>
        </tr>
    </apex:repeat>
</table>

 Javascript&colon;

 

<apex:outputPanel id="sliderWeights">
		<script>  
		var j$ = jQuery.noConflict();  
		
		 function popUpWeights() {//create sliders and put them in a pop up for the weights
		     j$( "div.weightSlider" ).slider({
		             min: 1, //these values need to be updated so they are dynamic
		             max: 10,
		             slide: function( event, ui ) {
		                 j$( "div.weightSlider" ).next().val(ui.value );
		             }
		         });
		
		     <apex:repeat value="{!standardConfigs}" var="sta">
		      j$( "#" + '{!sta.Section__c}' + '{!sta.Standard__c}' ).slider({
		              value: '{!sta.Default_weighting__c}',
		              min: 1,
		              max: 10,
		              slide: function( event, ui ) {
		                  j$( "#" + '{!sta.Section__c}' + 				'{!sta.Standard__c}').next("input").val(ui.value );
		              }
		          });
		         </apex:repeat>
		     j$( "#weighting" ).dialog({modal: true});
		 }
	 </script>
	</apex:outputPanel>

 Thanks again joshbirk!

 

 

This was selected as the best answer