JavaScript Syntax - Listbox onChange Event - javascript

First, please forgive me, as I know very little about JavaScript, and am trying to make something work without knowing proper terms and syntax. I am working within the CMS called "ViArt." A lot of what is going on is handled by php, and I only have access in ViArt to add JavaScript to an onChange event for a listbox.
Here is what I'm trying to accomplish:
The product is sunglasses. Different frame colors in a listbox 1 are designated by a numerical prefix. There are 30 different lens color options for each frame color, and these lens colors are chosen in listbox 2.
Using my current code, for each frame, I have to go in the JavaScript for each frame and manually enter the numerical prefix designated to that frame.
This is my current, working code in an onChange event:
=================================
var FrameNo = '01';//ENTER FRAME NUMBER
var ImagePath = 'images/GlassesBrand/Rx/GlassesTest/';//ENTER PATH TO IMAGES
var ImageNamePrefix = 'GlassesTest-XL';//ENTER NAMING CONVENTION
// This changes the IMAGE hyperlink to larger image to match user's selection
document.getElementById('blackImg').href=ImagePath + 'Large/' + ImageNamePrefix + '-Frame' + FrameNo + '-Lens' +
this.form.property{form_id}_{property_id}.options[this.form.property{form_id}_{property_id}.selectedIndex].text.substrin g(0,2) + '.jpg';
=================================
The change I want to make, is that I don't want to have to hard-code "FrameNo." I want to call that dynamically within the onChange event, by looking up the selectedIndex of listbox 1.
=============================
In an onChange event for list box 2, named "{property_id}," I am trying to get the selectedIndex of a listbox 1, named "{property_parent_id6385_6773}"
{form_id} value is 6385
{property_id} is listbox 2, and in this example, the value is 6773
{property_parent_id6385_6773} value is 6765, and in this example, this refers to listbox 1
{property_parent_id6385_6773} is named dynamically by a php script or something. For example, on the next form, it may be called {property_parent_id6400_6800}. So I am trying to program the JavaScript to dynamically refer to the property_parent_id####_####, based on whatever form and list box I'm working with.
When I hard-code or semi-hard code it for testing, the following methods work:
this.form.property6385_6765.selectedIndex;
and
this.form.property{form_id}_6765.selectedIndex;
I don't know the syntax, so I thought declaring some things in variables might help me get what I needed.
From my notes:
var FrameBox = [this.form.property_parent_id6385_6773.value]; //WHICH EQUALS "6765"
var FrameNo = 'this.form.property' + {form_id} + '_' + FrameBox + '.selectedIndex';
RESULTS IN:
http://www.companyname.com/images/GlassesBrand/Rx/GlassesTest/Large/GlassesBrand-GlassesTest-XL-Framethis.form.property6385_6765.selectedIndex-Lens02.jpg
Whereas, an example of the result I am seeking is:
http://www.companyname.com/images/GlassesBrand/Rx/GlassesTest/Large/GlassesBrand-GlassesTest-XL-Frame1-Lens02.jpg
==============================
In summary, I know what I need, but I don't understand enough of the syntax.
I know this could be better phrased, but this is all new to me. On the bright side, I am now inspired to take a class in JavaScript.
Any help would be greatly appreciated.

This is more of a calculated guess but could be worth a try.
this.form.property_parent_id{form_id}_{property_id}.options[this.form.property_parent_id{form_id}_{property_id}.selectedIndex].text

Related

Need option text from select field stored in Woocommerce order

I'm using custom post types in the woocommerce checkout page - to add details of a car entering a race. The car fields are pulled from the CPT car's based on the user_id logged in user. The problem I am facing is the value is getting stored in the order rather than the text of the field. eg. Ford, Fiesta, 2001, black,
what I am getting in the order is 488, 488, 488 etc
I am also storing the class the user is entering their car in - this too is showing correct on the front end - however storing the value in the back end. I've tried jquery/javascript - which I couldn't get to work.
code:
<script type="text/javascript">
var car_text = $("#my_car_select option:selected").text();
$(function(){
$('select').change(function(){
$('select').val( $(this).val() );
var selectedText = $("#my_car_select")[0].textContent
})
})
$car_selected_name = $('#my_car_select:selected').text();
$("#my_car_select").change(function(){
var car_text = $("#my_car_select option:selected").text();
});
</script>
I've also tried to query the CPT based on the ID - however this doesn't work either, I keep getting an array, not just the field text.
I am very frustrated as the option text is on the screen on the front end just not getting stored on the backend - Something really simple which I can't figure out. Any help would be greatly appreciated.
Thanks.
From what you have said it sounds like you just need to get the value from the selected option?
You almost have it right just need a space before :selected
e.g
var selected_text = $('#my_car_select :selected').text();
Which should return the selected element.
Let me know if this is still causing any issues, might help to see the source of the element you need to fetch this from.

Have a button open the right form JQuery

I have a while loop in my php page which sets a different id for every button and form through a counter variable. Every button has to open a different form (they each have different default information preselected, this is for a prescription renewal ability). I can get this to work by having in my javascript a click function for every id which calls a show on the right form. But, obviously this is not scalable, and so it cannot adapt to the amount of prescriptions I have. Looking through the web, I saw people using classes and the id starts with solutions to this problem. However, when I use this solution, the buttons open all the forms... not the desired behavior. Currently my javascript function is the following:
$('[id^="add-renew-link"]').click(function () {
$('[id^="add-renew-form"]').show();
});
Like mentioned above, the function does get called by all different IDs button. That code however opens all the forms every time one of the buttons get click. IDs are actually of the form add-renew-form0, add-renew-form1, add-renew-form2... (same pattern for add-renew-link). Forms and links with the same number at the end are meant to be linked. Does anybody know how I can achieve this? Thanks a lot!!
You can't have multiple DOM elements with the same ID. What you can do here is to assign classes for the elements:
<div class="add-renew-link"></div> <div class="add-renew-form"></div>
And then use .each
$('.add-renew-link').each( function(x){
$(this).click(function(){
$(".add-renew-form:eq("+x+")").show();
});
});
You can check out the JSFiddle here.
You're close. The $('[id^="add-renew-form"]').show(); is going to match ALL ELEMENTS that start w/ "add-renew-form" as the id, so that's why you're experiencing all forms being shown when clicking any link/button.
You can use a regex to pull the number from the end of the id to find a match on the associated form as below:
$('a[id^="add-renew-link"]').click(function() {
var idx = $(this).attr("id").match(/\d+$/)[0]; // Pull index number from id
$("#add-renew-form" + idx).show();
});
This jsbin has a full working example.
http://jsbin.com/xicuwi/1/edit
Try, using the .each() method:
$('[id^="add-renew-link"]').each(function(i){
var ths = $(this);
(function(i){
ths.click(function(){
$('#add-renew-form'+i).show();
}
})(i);
});

Turn JQuery Star Rating into Control

I have this fiddle, it's pretty cool, my first attempt at creating a jquery control. It is simple, just a star ratings control.
I want to be able to turn this into a control, so that, I can call:
$('#someDiv').starRating();
And it turns that div into a star rating.
I would like to be able to then setup some properties:
Empty Star Source
Hover Star Source
Star Rating (leave blank if new rating)
So it would look something like this:
$('#someDiv').starRating({
emptyStarSource : 'http://www.imageland.com/image.png',
hoverStarSource : 'http://www.imageland.com/image.png',
initialRating : 3
});
Similar to the Datepicker in how to change options etc.
If anyone could point me in the right direction that would be awesome!
EDIT
So I have had a go with the help of the answer I got. The img click events aren't working, I'm guessing that somehow I have to attach the click handlers after I append them to the page. how? After that, I just need to do the settings!
ratings control
To write a plugin in jQuery use the following syntax
$.fn.setRed = function(){
return $(this).each(function(){ //this is required for jQuery chaining to work and also if multiple html objects are passed
var _obj = $(this);
//work on the object here
_obj.css("background-color", "red");
});
}
You can then use
$(".ratings").setRed();

How to deal with dynamic properties in Backbone and sync to database

I have been struggling with Backbone the last few days in trying how to best approach dealing with some dynamic elements added by a user and sync those successfully with the database. I have one model and one view.
The model created is fairly straightforward, it represents a product(t-shirt) in a database and has the attributes: id, price, size, brand, colors.
The problem I am faced with is the colors attribute. The colors cannot be pre-populated by design (unfortunate as it may be) to allow for the user to enter any custom color and name it as freely as they want. In addition to the name, the user has to specify if the color is available. Clicking the Add Text button/link will have an input field and dropdown appended to the div below.
My question: What is the best way to add these multiple color properties as ONE attribute of the model?
I need to have all the colors/availability values as one property when it attempts to insert or update itself with the API as the colors property and goes into one row in the db (mysql). I believe the backend programmer has this row configured as a type of TEXT.
e.g.
{"colors": [{"blue":true},{"orange":false},{"white":false}]}
My thinking is that I need to obviously have some sort of nested JSON within the model but I can't figure out how to write this properly. Any help or something to point me in the right direction would be much appreciated.
Ok, this solution involves jQuery maybe a bit too much, but should work fine. Basically, listen to both changes of your color textboxes and select:
events: {
'change .colorText': 'setColor',
'change .colorSelect': 'setColor'
},
setColor: function() {
// here make your `color` attribute's array
var colors = [];
this.$('.colorText').each(function() {
var val, color;
// adapt the next to navigate to the corresponding select...
(val = $(this).val()) && (((color = {})[val] = $(this).next().val()) || 1) && colors.push(color);
});
this.model.set('colors', colors);
}

How to update ZK Grid values from jQuery

I have three Tabs and in each tab, I have a Grid.
The data for each Grid is coming from a database, so I am using rowRenderer to populate the Grids. The following code is common for all three Grids:
<grid id="myGrid1" width="950px" sizedByContent="true" rowRenderer="com.example.renderer.MyRowRenderer">
The rows are constructed from Doublebox objects. The data is populated successfully.
The Problem:
I need to handle multiple-cell editing on the client side. The editing is done via mouse-clicking on a particular cell and entering a value.
As example let's say that the user edits first cell on the first row and the value should be
propagated to all other cells on the same row and in all three Grids (so also the two Grids which the user currently does not see, because they are in tabpanes).
I am using jQuery to do this value propagation and it works OK.
I am passing the jQuery as follows:
doublebox.setWidgetListener(Events.ON_CHANGING, jQuerySelectors);
doublebox.setWidgetListener(Events.ON_CHANGE, jQuerySelectors);
This makes it possible to change the value in 1 cell and the change is instantly (visually) seen in all other cells filtered by jQuery selectors.
The problem is that the value is visually distributed to all the cells, but when I try to save the Grid data back to the database, the background values are the old ones.
I am assuming that ZK-Grid component is not aware that jQuery changed all the cell values. Nevertheless if I manually click on a cell that already has the NEW value (enter/leave/change focus) when I save the grid the NEW value is correct in that particular cell. Maybe that's a hint how can I resolve this.
Code of how I extract the Grid values:
Grid tGrid = (Grid) event.getTarget().getFellow("myGrid1");
ListModel model = tGrid.getModel();
MyCustomRow tRow = (MyCustomRow)model.getElementAt(i);
The model for my Grid is a List of MyCustomRow:
myGrid1.setModel(new ListModelList(List<MyCustomRow> populatedList));
I have a couple of assumptions, but whatever I have tried, hasn't worked. I have in mind that jQuery events and ZK-Events are different and probably isolated in different contexts. (Although I have tried to fire events from jQuery and so on..)
Do you have any suggestions? As a whole is my approach correct or there's another way to do this? Thanks for your time in advance!
Your problem is exactly what you are expecting.
Zk has it's own event system and do not care about your jq,
cos it's jq and zk don't observ the DOM.
The ways to solve your problem.
Use the "ZK-Way":
Simply listen at server-side and chage things there.
I am not sure if not selected Tabs
are updateable, but I am sure you could update the Grid
components on the select event of the Tab.
Fire an zk-event your self:
All you need to know, is written in the zk doc.
Basically, you collect your data at client side, send
an Event to the server via zAu.send() extract the
data from the json object at serverside and update your Grids
I would prefer the first one, cos it's less work and there should not be
a notable difference in traffic.
I post the solution we came up with:
This is the javascript attached to each Doublebox in the Z-Grid
//getting the value of the clicked cell
var currVal = jq(this).val();
//getting the next cell (on the right of the clicked cell)
objCells = jq(this).parents('td').next().find('.z-doublebox');
// if there's a next cell (returned array has length) - set the value and
// fire ZK onChange Event
if (objCells.length) {
zk.Widget.$(jq(objCells).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCells).attr('id')).fireOnChange();
} else { //otherwise we assume this is the last cell of the current tab
//So we get the current row, because we want to edit the cells in the same row in the next tabs
var currRow = jq(this).parents('tr').prevAll().length;
//finding the next cell, on the same row in the hidden tab and applying the same logic
objCellsHiddenTabs = jq(this).parents('.z-tabpanel').next().find('.z-row:eq(' + currRow + ')').find('.z-doublebox');
if (objCellsHiddenTabs.length) {
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).fireOnChange();
}
}
The java code in the RowRenderer class looks something like this:
...
if (someBean != null) {
binder.bindBean("tBean", someBean);
Doublebox box = new Doublebox();
setDefaultStyle(box);
row.appendChild(box);
binder.addBinding(box, "value", "tBean.someSetter");
...
private void setDefaultStyle(Doublebox box) {
box.setFormat("#.00");
box.setConstraint("no negative,no empty");
box.setWidth("50px");
String customJS = ""; //the JS above
//this is used to visually see that you're editing multiple cells at once
String customJSNoFireOnChange = "jq(this).parents('td').nextAll().find('.z-doublebox').val(jq(this).val());";
box.setWidgetListener(Events.ON_CHANGING, customJSNoFireOnChange);
box.setWidgetListener(Events.ON_CHANGE, customJS);
}
What is interesting to notice is that ZK optimizes this fireOnChange Events and send only 1 ajax request to the server containing the updates to the necessary cells.

Categories

Resources