Javascript variable cut off after apostrophe - javascript

I have a Javascript which reads the text from two HTML drop-down lists, removes all special characters, and then stores the text in a variable. The text in the drop-down lists are coming from a JSON file. The problem is that whenever the text from the drop-down lists has an apostrophe, the Javascript cuts the string at the apostrophe, hence all text after the apostrophe is not included in the Javascript variable.
I have included a replace rule to try and replace all apostrophes with a non-space, but no luck. I cannot avoid the problem by using HEX codes, since the Javascript reads text directly from the HTML drop-down lists.
Example: If a user selects "Belgium" and "Braine-l'Allerud" in the drop-down lists, the javascript should create a variable "Cities-belgium-brainelallerud.html". Instead, it cuts all text after the apostrophe in "Braine-l'Allerud" and instead creates a variable "Cities-belgium-brainel.html"
Here is the JSON file (basis for the text in drop-down lists):
"austria": "Hirschegg,Salzburg,Bergheim,Wien",
"belgium": "Antwerpen,Braine-l'Alleud,Brugge"
And here is the Javascript code:
jQuery( "button[type='submit']" ).click(function(e) {
e.preventDefault()
var var1 = $('#json-one').val()
var var2 = $('#json-two').val().toLowerCase().replace(/'/g,"").replace(/[^a-zA-Z0-9_-]/g,'')
var link = "Cities-"+var1+"-"+var2+".html"
console.log(link)
document.location = link;
});
The JSON values are extracted into the drop down lists by the following script:
$(document).ready(function(){
$("#json-one").change(function() {
var $dropdown = $(this);
$.getJSON("../jsondata/data003.json", function(data) {
var key = $dropdown.val();
var vals = [];
switch(key) {
case 'austria':
vals = data.austria.split(",");
break;
case 'belgium':
vals = data.belgium.split(",");
break;
}
var $jsontwo = $("#json-two");
$jsontwo.empty();
$.each(vals, function(index, value) {
$jsontwo.append("<option value='"+value+"'>" + value + "</option>");
});
});
});
$("#json-one").trigger('change');
});
The drop-down list is dynamic; the 2nd drop down list (cities) is dependent on what the user chooses in the 1st drop down list (countries).
Finally, the drop down list is written as follows in the HTML:
<span class="fontyellow">Country:</span>
<select id="json-one">
<option value="austria">Austria</option>
<option value="belgium">Belgium</option>
</select>
<span class="fontyellow">City:</span>
<select id="json-two">
</select>
Thanks in advance.

Ok, the problem is in your dynamic construction of the options. You have organized your apostrophes in this manner:
$jsontwo.append("<option value='"+value+"'>" + value + "</option>");
As a result, the single quote is surrounding the city name in the 'value' portion of this string and hence the string is cutoff at the first single apostrophe it runs into. Basically it looks like this when constructed:
<option value='Braine-l'Alleud'>Braine-l'Alleud</option>
You need to use double quotes for that portion of the string instead:
$jsontwo.append('<option value="'+value+'">' + value + "</option>");
That will fix the problem and give you the following:
<option value="Braine-l'Alleud">Braine-l'Alleud</option>

I am not sure why you are generating the link the way you are but if you replace the code from jQuery to javascript, it should be able to read the text.
Like below:
var var1 = document.getElementById("json-one").innerText;
var var2 = document.getElementById("json-two").innerText;
I put the html in div like below:
<div id="json-one">Hirschegg,Salzburg,Bergheim,Wien</div>
<div id="json-two">Antwerpen,Braine-l'Alleud,Brugge</div>
OR
replace .val() to .html() like below:
var var1 = $('#json-one').html();
var var2 = $('#json-two').html();
See if it helps!

Related

Having difficulty building a form summary with JS

Sorry for the noobish question but, I am trying to build a form summary that will populate a div (immediately) with all of the fields being used. Here is a small sample of the field: Fiddle
For some reason the JS is not working as I would expect it to, can anyone point out what I am doing wrong?
For example, I would like it to output: "AND name: john EXCEPT number 222".
I would also like to be able click on a result to remove it, and clear the field. Thank you
$(".allS").change(function () {
if ($(this).next('.textArea').not(':empty'))
// varible to hold string
var str = "";
$("select option:selected").each(function () {
str += $(this).text() + " ";
});
$("#text_here").text(str);
}).change();
$('.textArea').change(function(){
var $inputs = $('form#form :input[type="text"]'),
result = "";
$inputs.each(function(){
// access the individual input as jQuery object via $(this)
result += $(this).val()+"<br>";
});
// store result in some div
$('div#text_here').text(result);
}).change();
There were many mistakes in your code. I simplified it to a very short code that only does what's needed to get the output you requested. Here's the working fiddle.
$(".allS, .textArea").change(function () {
var str = '';
if ($('#name').val().length > 0 && $('#number').val().length > 0)
var str = $('#nameMod>option:selected').text() + ' name:' + $('#name').val() + ' ' + $('#numberMod>option:selected').text() + ' number ' + $('#number').val();
$("#text_here").html(str);
});
Basically, what this does is attach a change event handler to both classes (.alls, .textArea), and when the event is triggered, both input fields are tested for any content. If this test passes, a string is composed out of all the relevant values, and the div content is set. If the test failed (no content), the str variable contains an empty string and the div is cleared.
Just glancing at the code, the selector 'form#form :input[type="text"]' looks wrong. For starters, input is not a pseudoclass. Also, attribute matching shouldn't have the quotes.
This may or may not be what you want (I think it is, from looking at your html):
'form#form input[type=text]'
Also your <br>'s are not working because you called text(). call html() instead.

How to iterate through HTML nodes to find matches and get the next innerHTML from a node

I have a form element <select> to select a person. As soon as the element has changed
the function getPerson() is executed and reads out the value of the selected entry.
<select id="cust_id" name="f_cust_id" onchange="getPerson(this)">
<option value="51">Brad Pitt</option>
<option value="123">Angelina Jolie</option>
<option value="13">Jennifer Aniston</option>
</select>
The next step is: that I have a hidden text in the same page, where I want to find this value (example value 51).
I need to iterate trough this hiddenCustomer nodes.
Hidden HTML Text
<div id="hiddenCustomer" style="display:none;">
<span>51</span><span>Brad;Pitt;Y1;Group1;bpitt#wwz.com;12345</span>
<span>123</span><span>Angelina;Jolie;Y2;Group2;ajolie#wwz.com;12346</span>
<span>13</span><span>Jennifer;Aniston;Y1;Group1;ja#wwz.com;12347</span>
</div>
finally if I have a match 51=51 I take the string from the next element and "split" it to an array. It will be used to fill out some formular fields like: firstname, lastnamem, floor, group, email...
My question is: how to iterate best trough the hiddenCustomer nodes. Find the match and take the innerHTML value from
the next element ( example : Brad;Pitt;Y1;Group1;bpitt#wwz.com;12345)
ps: I don't want to use JSON Objects.
You can do like this
[DEMO] --> http://fiddle.jshell.net/ykF6P/
function getPerson(element)
{
var val = element.value;
var $span = $('#hiddenCustomer span').filter(function(){
return $(this).text() == val;
}).next('span');
}
function getPerson(element){
var elementsArray = [];
$("#hiddenElement").each(function(){
$(this).find("span").each(function(){
if($(this).text() == $(element).val()){
elementsArray = $(this).find("span").next().text().split(';');
}
});
});
}
You end up with an array of strings.
You can do this:
var value = 51;
var $span = $('#hiddenCustomer span:nth-child(odd)').filter(function(){
return parseInt($(this).text(),10) == value;
}).next('span');
console.log($span.html());

How can I create dynamic controls and put their data into an object?

I created a div and a button. when the button clicked, there will be a group of element(included 1 select box and 2 text inputs) inserted into the div. User can add as many group as they can, when they finished type in data of all the group they added, he can hit save button, which will take the value from each group one by one into the JSON object array. But I am stuck in the part how to get the value from each group, so please help, thank you.
The code for the div and the add group button function -- AddExtra() are listed below:
<div id="roomextra">
</div>
function AddExtra() {
$('#roomextra').append('<div class=extra>' +
'<select id="isInset">' +
'<option value="Inset">Inset</option>' +
'<option value="Offset">OffSet</option>' +
'</select>' +
'Length(m): <input type="text" id="insetLength">' +
'Width(m): <input type="text" id="insetWidth">' +
'Height(m): <input type="text" id="insetHeight">' +
'</div>');
}
function GetInsetOffSetArray (callBack) {
var roomIFSDetail = [{
"IsInset": '' ,
"Length": '' ,
"Width": '' ,
"Height": ''
}];
//should get all the value from each group element and write into the array.
callBack(roomIFSDetail);
}
This should just about do it. However, if you're dynamically creating these groups, you'll need to use something other than id. You may want to add a class to them or a data-* attribute. I used a class, in this case. Add those classes to your controls so we know which is which.
var roomIFSDetail = [];
var obj;
// grab all of the divs (groups) and look for my controls in them
$(.extra).each(function(){
// create object out of select and inputs values
// the 'this' in the selector is the context. It basically says to use the object
// from the .each loop to search in.
obj = {
IsInset: $('.isInset', this).find(':selected').val() ,
Length: $('.insetLength', this).val() ,
Width: $('.insetWidth', this).val() ,
Height: $('.insetHeight', this).val()
};
// add object to array of objects
roomIFSDetail.push(obj);
});
you'd better not to use id attribute to identity the select and input, name attribute instead. for example
$('#roomextra').append('<div class=extra>' +
'<select name="isInset">' +
'<option value="Inset">Inset</option>' +
'<option value="Offset">OffSet</option>' +
'</select>' +
'Length(m): <input type="text" name="insetLength">' +
'Width(m): <input type="text" name="insetWidth">' +
'Height(m): <input type="text" name="insetHeight">' +
'</div>');
}
and then, usr foreach to iterate
$(".extra").each(function() {
var $this = $(this);
var isInset = $this.find("select[name='isInset']").val();
var insetLength = $this.find("input[name='insetLength']").val();
// ... and go on
});
A common problem. A couple things:
You can't use IDs in the section you're going to be repeating, because IDs in the DOM are supposed to be unique.
I prefer to use markup where I'm writing a lot of it, and modify it in code rather than generate it there.
http://jsfiddle.net/b9chris/PZ8sf/
HTML:
<div id=form>
... non-repeating elements go here...
<div id=roomextra>
<div class=extra>
<select name=isInset>
<option>Inset</option>
<option>OffSet</option>
</select>
Length(m): <input id=insetLength>
Width(m): <input id=insetWidth>
Height(m): <input id=insetHeight>
</div>
</div>
</div>
JS:
(function() {
// Get the template
var container = $('#roomextra');
var T = $('div.extra', container);
$('#addGroup').click(function() {
container.append(T.clone());
});
$('#submit').click(function() {
var d = {};
// Fill d with data from the rest of the form
d.groups = $.map($('div.extra', container), function(tag) {
var g = {};
$.each(['isInset', 'insetLength', 'insetWidth', 'insetHeight'], function(i, name) {
g[name] = $('[name=' + name + ']', tag).val();
});
return g;
});
// Inspect the data to ensure it's what you wanted
debugger;
});
})();
So the template that keeps repeating is written in plain old HTML rather than a bunch of JS strings appended to each other. Using name attributes instead of ids keeps with the way these elements typically work without violating any DOM constraints.
You might notice I didn't quote my attributes, took the value attributes out of the options, and took the type attributes out of the inputs, to keep the code a bit DRYer. HTML5 specs don't require quoting your attributes, the option tag's value is whatever the text is if you don't specify a value attribute explicitly, and input tags default to type=text if none is specified, all of which adds up to a quicker read and slimmer HTML.
Use $(".extra").each(function() {
//Pull info out of ctrls here
});
That will iterate through all of your extra divs and allow you to add all values to an array.

Stop a page from refreshing after firing a function

I've been tasked with building a very simple app that that has a series of dropdowns in rows of 2, when 2 are selected, a simple functions concatenates the 2 values and gives an output next to them like so:
dropdown1 dropdown2 Output
What I'm trying to get is, once the second dropdown value is chosen the function runs and displays the output where it says output. But currently, what seems to happens is the output is displayed in a new window.
Here's what I have so far (HTML):
<form>
<select id="test">
<option>Arena/Quantum Barcelona LTBC</option>
<option>Arena/Quantum Spain LTES</option>
</select>
<select id="name" onchange="tryThis()">
<option>Name</option>
<option>Name1</option>
</select>
</form>
JavaScript:
function tryThis() {
var string, string1 = '';
var e = document.getElementById("test");
string = e.options[e.selectedIndex].text;
var a = document.getElementById("name");
string1 = a.options[a.selectedIndex].text;
document.write(string+'_'+string1);
}
Am I making this more difficult than it needs to be?!
That's because document.write clears the page before displaying something. You should never need to use that function.
Instead, you could append it to e.g. the body:
document.body.appendChild(
document.createTextNode(string + '_' + string2)
);
Have you noticed that your JS function is called tryThis() and on the event handler you're calling tryThsis()
However in your case I'd refrain from using document.write, good alternatives are appending to the body or having a DIV and changing the innerHTML of that DIV
First put an id on your form so that it is easier to access.
var a = (function () {
var myForm = document.getElementById("myForm"),
magic = function () {
var a = myForm.getElementsByTagName("select"),
b,
c = [];
for (b = a.length - 1; b > -1; b -= 1) {
c.push(a[b].value);
}
alert(c.join(" ") + " output");
};
myForm.onclick = magic;
}());
You were not specific as to what the extra "output" is supposed to be or how you want the data returned, but here you go. Instead of using an alert you could push the result into the value of a different form element. Do not use document.write as this cannot be deferred. If you attempt to defer a document.write operation it will replace the entirety of the body contents of the current page.

Need to combine values from multiselect option to form a url with javascript

I am using an application that allows real estate searching on my site. The app came with a very limited search functionality form, so I've taken it and tried to enhance it by way of URL parameters that the IDX solution provider provides. One of these parameters is to make a URL and combine multiple city names in order to search for listings in more than one city at a time. I've added a multi select field to the form, but the problem is that each city has to have a sequential number in between < > symbols.
So the search would end up looking like this and the first city has to be number <0>:
www.yourblog.com/idx/?idx-q-Cities<0>=Irvine&idx-q-Cities<1>=Laguna%20Beach
I need a way tfor the options selected in the multiple select field to be combined to achieve the above result.
Here is what the part of the form with the multi select looks like.
<form action="http://www.mmysite.com/idx/" method="get" onsubmit="prepareSearchForm(this)">
<table>
<tr>
<th><label for="idx-q-Cities">Select Your Cities</label></th>
<td>
<select multiple name="idx-q-Cities" title="Type or select your cities">
<option id="idx-q-Cities" class="idx-q-Cities" value="Abbeville">Abbeville</option><br>
<option id="idx-q-Cities" class="idx-q-Cities" value="Abilene">Abilene</option>
</select>
</tr>
</table>
</form>
I had someone helping me try to get this to work, but it was unsuccessful. Here is what they came up with. Maybe it will help.
<script>
function prepareSearchForm(form){
var count = 0;
$(form).children('.idx-q-Cities').each(function(i,o){
var cityDOM = document.createElement('select');
cityDOM.name = "idx-q-Cities<" + count++ + ">";
cityDOM.value = o.value;
form.appendChild(cityDOM);
});
return true;
}
</script>
Any ideas on how to correct the above JS or another way to take the multi select options and combine them in order to end up with the URL above?
Well, I'll offer you this:
function prepareURL() {
var vals = $('select option:selected').map(
function(i){
return $(this).attr('class') + '<' + i + '>=' + $(this).val();
}).get().join(';');
var URL = 'www.yourblog.com/idx/' + vals;
$('#urloutput').text(URL);
}
$('select').click(
function() {
prepareURL();
});
JS Fiddle demo.
But I'm not sure if you want the first selected 'get' option to be 0 (whether that's Abeline or Abbeville), or if you want the Abbeville to always be the 0 option and Abeline to always be the 1 option. So I offer you an option based on that possibility too:
function prepareURL() {
var vals = $('select option:selected').map(
function(){
return $(this).attr('class') + '<' + $(this).index('select option') + '>=' + $(this).val();
}).get().join(';');
var URL = 'www.yourblog.com/idx/' + vals;
$('#urloutput').text(URL);
}
$('select').click(
function() {
prepareURL();
});
JS FIddle demo.
Also, given that this appears to be a GET string, I can't help but feel you should have a ? in the URL somewhere. But I leave that to you to implement, in case you don't want it there, for some reason.
And, as a (final?) addenda, I'd strongly suggest URL-encoding the vals variable before submitting it as a URL:
var URL = 'www.yourblog.com/idx/' + encodeURIComponent(vals);
$('#urloutput').text(URL);
JS Fiddle demo.
If you are using PHP then change:
<select multiple name="idx-q-Cities" title="Type or select your cities">
To:
<select multiple name="idx-q-Cities[]" title="Type or select your cities">
Your javascript is for sure wrong. Do this on the server end.

Categories

Resources