onchange handler with quoted text - javascript

I want to use some inline javascript/jquery in an on change handler of a radio button:
<input
name="Operator"
type="radio"
value="#Model.Operator"
checked="true"
onChange="#radioOnChange"
/>
The test version of radioChange looks like this:
#{
const string radioOnChange =
"var name = $(this).attr('name');" +
"alert(name);" +
"var selector = "span[name='" + name + "']"; "+
"alert(selector);
}
For the "var selector = "span['+name+']"" part I tried a zillion different variations using "\" the html "&" escapes, etc. But right one eludes me.

I guess the right one should be: "var selector = "span[name='" + name + "']"; ", which will produce: var selector = "span[name='selectorName']";
I also recommend using \" instead of " - I guess it's all the same but more readable (maybe someone should correct me if I'm wrong?)

Found out that the trick was using a McvHtmlString like so:
<input
name="Operator"
type="radio"
value="#Model.Operator"
checked="true"
onChange="#MvcHtmlString.Create(radioOnChange)"
/>

Related

Is there a simpler way to do this script?

I'm learning and trying to put together a little bit of jquery. Admittedly I'm finding it difficult to find a good basics guide, particularly, when adding multiple actions to one page.
I read somewhere that the document listener should only be used once. I believe I'm using it twice here, but not 100% sure how to bring it into one listener.
Also because I've been hacking bits of script together, I think I'm using parts of javascript and parts of jQuery. Is this correct?
A critique of the code below [which does work] and any advice on how best to approach learning jQuery would be most helpful. Thanks.
Script 1 styles a group of 3 radio buttons depending on which one is clicked.
Script 2 appends new inputs to the bottom of a form.
var stateNo = <?php echo $HighestPlayerID; ?> + 1;
$(document).on('click', 'input', function () {
var name = $(this).attr("name");
if ($('input[name="' + name + '"]:eq(1)')[0].checked) {
$('label[name="' + name + '"]:eq(1)').addClass('nostate');
$('label[name="' + name + '"]').removeClass('selected');
}
else {
$('label[name="' + name + '"]').removeClass('nostate selected');
if ($('input[name="' + name + '"]:eq(0)')[0].checked) {
$('label[name="' + name + '"]:eq(0)').addClass('selected');
}
else {
$('label[name="' + name + '"]:eq(2)').addClass('selected');
}
}
});
$(document).on('click', 'button[name=btnbtn]', function () {
var stateName = 'state[' + stateNo + ']';
var newPlayerAppend = `` +
`<tr><td>` +
`<input type="hidden" name="state['` + stateNo + `'][PlayerID]" value="` + stateNo + `" /></td>` +
`<td><input name="` + stateName + `[Name]" value="Name"></td>` +
`<td><input name="` + stateName + `[Team]" type="radio" value="A">` +
`<td><input name="` + stateName + `[Team]" type="radio" value="">` +
`<td><input name="` + stateName + `[Team]" type="radio" value="B">` +
`</td></tr>`;
$("tbody").append(newPlayerAppend);
stateNo++;
});
HTML for the 3 radio button inputs
<td class="Choice">
<label name="state[1][Team]" class="teampick Astate ">A
<input name="state[1][Team]" type="radio" value="A" />
</label>
<label name="state[1][Team]" class="smallx nostate ">X
<input name="state[1][Team]" type="radio" value="" checked />
</label>
<label name="state[1][Team]" class="teampick Bstate">B
<input name="state[1][Team]" type="radio" value="B" />
</label>
</td>
Some of the code can be written more concisely, or more the jQuery way, but first I want to highlight an issue with your current solution:
The following would generate invalid HTML, if it were not that browsers try to solve the inconsistency:
$("tbody").append(newPlayerAppend);
A tbody element cannot have input elements as direct children. If you really want the added content to be part of the table, you need to add a row and a cell, and put the new input elements in there.
Here is the code I would suggest, that does approximately the same as your code:
$(document).on('click', 'input', function () {
$('label[name="' + $(this).attr('name') + '"]')
.removeClass('nostate selected')
.has(':checked')
.addClass(function () {
return $(this).is('.smallx') ? 'nostate' : 'selected';
});
});
$(document).on('click', 'button[name=btnbtn]', function () {
$('tbody').append($('<tr>').append($('<td>').append(
$('<input>').attr({name: `state[${stateNo}][PlayerID]`, value: stateNo, type: 'hidden'}),
$('<input>').attr({name: `state[${stateNo}][Name]`, value: 'Name'}),
$('<input>').attr({name: `state[${stateNo}][Team]`, value: 'A', type: 'radio'})
)));
stateNo++;
});
There is no issue in having two handlers. They deal with different target elements, and even if they would deal with the same elements, it would still not be a real problem: the DOM is designed to deal with multiple event handlers.
There are 2 places you are using anonymous functions. If the code block moves to a named function, the entire code becomes more maintainable. It also helps better in debugging by telling you upfront which function name the error may lie in.
Once you have named functions you will realise that you really do have 2 event listeners for click. So there isn't much benefit of moving them in one listener (or one function you may be referring to). These both event listeners attach on document object and listen to a click event.
Class names are always better when hyphenated. a-state over Astate.
If it works it is correct code, for once you asked about correctness.
It is absolutely fine to have multiple listeners but I usually prefer making everything under one roof. Consider making code as simple as possible which saves lot of time during maintenance.
you can use $(function() {}) or document.ready().
$(document).ready(function() {
$('input[type="radio"]').click(function() {
var thisa = $(this).parent();
var name = $(this).attr("name");
// Remove :selected class from the previous selected labels.
$('label[name="' + name + '"]').removeClass('selected');
// Add conditional class with tenary operator.
thisa.parent().hasClass("smallx") ? thisa.addClass('nostate') : thisa.addClass('selected');
});
$('button[name=btnbtn]').click(function() {
var stateName = 'state[' + stateNo + ']';
// Add TR and TD before appending the row to tbody
var newPlayerAppend = `<tr><td>` +
`<input type="hidden" name="state['` + stateNo + `'][PlayerID]" value="` + stateNo + `" />` +
`<input name="` + stateName + `[Name]" value="Name">` +
`<input name="` + stateName + `[Team]" type="radio" value="A"></td></tr>`;
$("tbody").append(newPlayerAppend);
stateNo++;
});
});
Hope this helps.

how to delete a value between <input> tags?

I'm creating checkboxes using JQuery as following:
$('<input type="checkbox" ' + 'id=' + (i+1) + '>' + (i+1) + '</input><br/>')
Then later it is removed whenever the user checks the box in:
if (this.checked) {
$(this).remove();
}
However, The input box is deleted, but the number (id) stays on the page, along the <br/> Tag, so I can see the #i there on the HTML Page.
I would like to remove them as well.
So, to in order to make my question as complete as possible, here is how the HTML is laid:
<input id="1" type="checkbox">
1
<br>
Could someone please give me a clue how to remove #i and <br/> from the page?
Thanks
as stated by other answers - input don't have closing tags
You will still need to remove all id and <br />. You can find those with .next() function in jquery. You should put your id in <label> or <span>.
Then. for example:
$(this).next('label').remove();
$(this).next('br').remove();
$(this).remove();
Code can be written shorter but it's for you to see how it works.
The text in <input> text boxes is not set with a textnode (like for textareas), but with the value attribute. (Sorry for the confusion)
Yet, you want to have a checkbox. Best, create a <label> for it, instead of a text node plus a <br /> (which is not handleable with jQuery):
<div class="inputcell">
<input type="checkbox" id="check5">
<label for="check5">5</label>
</div>
With this DOM, you can easily remove the whole box by $("#check5").parent().remove(). Note that single numbers are no valid element ids.
that's because input tags don't have closing tags and remove ignores everything after the >, change this:
$('<input type="checkbox" ' + 'id=' + (i+1) + '>' + (i+1) + '</input><br/>')
to:
$('<input type="checkbox" ' + 'id=' + (i+1) + 'value="' + (i+1) +'"><label>'+ (i+1) +'</label>')
$(this).next('label').andSelf().remove();
input tags don't have closing tag, to create a checkbox you just need the following:
$('<input type="checkbox" ' + 'id=' + (i+1) + '>');
and if you want also to use a label for that checkbox, create appropriate label or any other element, because you can't put closign tag for input and a text between them

simpler way of grouping numerous variables by value of select?

thanks for looking.
im still learning the more complex javascript and jquery coding so could do with some help as i have no idea about the following or even if its possible!
i need a better/simpler/shorter way of doing the following (please note i have removed the irrelevant validation etc coding):
'
function Findbox5( myform, box1, box2, box3, box4, box5, Storeall, s1, s2, s3, s4, s5)
{
//store values
Myform = document.forms.myform;
box1 = Myform.box1.value;
box2 = Myform.box2.value;
box3 = Myform.box3.value;
box4 = Myform.box4.value;
box5 = Myform.box5.value;
s1 = Myform.s1.value;
s2 = Myform.s2.value;
s3 = Myform.s3.value;
s4 = Myform.s4.value;
s5 = Myform.s5.value;
//set as one string
Storeall = s1 + ":" + box1 + ";" + s2 + ":" + box2 + ";" + s3 + ":" + box3 + ";" + s4 + ":" + box4 + ";" + s4 + ":" + box5 + ";" ;
// next function...
} '
as you can see i have 5 input boxes and relevant selects for each box(each select has 4 options:1,2,3,4.). when a user enters data into a box they choose a relevant option. all boxes and options must be entered then they submit the form.
this data will be emailed to me as the variable stored under storeall. which would be something like 1:1234;2:1324;1:3232;4:5434;2:3211;
so what i hope to do is simplify this data into the following with either a seperate function or the same one: 1:1234-3232;2:1324-3211;4:5434;
is this possible? or have i done it the easiest way?
any comments or help welcomed, thanks again
First, you'll want to group these things into a single element that can be iterated against. So if your HTML looks like:
<form>
<input name="s1" />
<input name="box1" />
<input name="s2" />
<input name="box2" />
...
</form>
Then it's probably better to do something like:
<form>
<div class="set">
<input class="s" name="s1" />
<input class="box" name="box1" />
</div>
<div class="set">
<input class="s" name="s2" />
<input class="box" name="box2" />
</div>
...
</form>
Now you've established some commonality among these elements, instead of just different names/IDs. Each set of inputs is grouped by the .set class, and within each set, you know there's going to be two inputs: one with the .s class, and one with the .box class. Now iterating against them with JQuery is easy:
var str = "";
$("form div.set").each(
function(index, element)
{
currentValueS = $(element).find("input.s").val();
currentValueBox = $(element).find("input.box").val();
str += currentValueS + ":" + currentValueBox + ";";
}
);
This uses JQuery's .each() function. .each() allows you to provide a function to perform on each of the elements that JQuery finds from the indicated selector. Here, your selector is form div.set, which means "all div elements that have the class of .set, and are found anywhere under any form element". For each of these elements, you'll need to find the value of the <input> element with the .s class, and also the value of the <input> element with the .box class. Then you just add those to your growing str variable.
If you want everything in the form, you should use serializeArray :
$('#my_form').submit(function() {
var str = '';
$.each($(this).serializeArray(), function () {
str += this.name + ":" + this.value + ";";
});
sendByMail(str);
return false;
});

jquery with index based radio button selected value help

I have following generated code and tried to retrive the radio button value or checked from below html generated code
HTML code generated :::
<input type="radio" name="mergedServiceSets[0].cdaQuestionnaireresponses[0].questionnaire.value" id="SetUpTest_mergedServiceSets_0__cdaQuestionnaireresponses_0__questionnaire_valueY" value="Y" class="mergedServiceSets[0].cdaQuestionnaireresponses[0].questionInputRadio" onchange="javascript:dataModified();"/> Yes<br />
<input type="radio" name="mergedServiceSets[0].cdaQuestionnaireresponses[0].questionnaire.value" id="SetUpTest_mergedServiceSets_0__cdaQuestionnaireresponses_0__questionnaire_valueN" value="N" class="mergedServiceSets[0].cdaQuestionnaireresponses[0].questionInputRadio" onchange="javascript:dataModified();"/> No<br />
Jquery1.6.1 used :
var questionInputRadio = $(".mergedServiceSets[" + i + "].cdaQuestionnaireresponses[" + j + "].questionInputRadio");
where i and j are passed dynamically .
or
alert("questionInputRadio===" + $(".mergedServiceSets[0].cdaQuestionnaireresponses[0].questionInputRadio").val());
Actual results ::: undefined is displaying when i see in alert box .
It never works for index based classes or ids in jquery . please help
You need to escape [, ] and . in your selector. Something like:
$(".mergedServiceSets\\[" + i + "\\]\\.cdaQuestionnaireresponses\\[" + j + "\\]\\.questionInputRadio");
Edit: I'm actually not sure if those characters are even technically valid.

Need help with regular expression and javascript

I've following problem: I use a clone script to clone input fields which are used for cms options. Depending on the field name the option arrays are created in the db.
I have following field at the moment:
options[categories][1][3]
and want to increase the first number by using a counter variable like:
options[categories][2][3]
options[categories][3][3]
...
However I'm not familiar with regular expressions so I hoped someone could provide a str.replace code which helps me to replace the first number with my counter variable.
Thanks in advance!
.......
Code:
.......
At the moment it looks like:
if ( $(clone).attr('name') ){
newid = $(clone).attr('name');
var position = newid.lastIndexOf("[");
newid = newid.substring(0, position)+ '[' + (counter +1) + ']';
$(clone).attr('name', newid);
};
Html field:
<input type="checkbox" value="1" name="options[categories][1][3]">
3 is the category id, 1 is the option I need the category for. The clone script would produce:
<input type="checkbox" value="1" name="options[categories][1][4]">
at the moment - but I need:
<input type="checkbox" value="1" name="options[categories][2][3]">
I think it's a regex problem because the easiest solution would be to search for [categories][anyvalue] and replace it with [categories][counter]
You could use a regular expression to replace the first number in brackets. Like this:
if ( $(clone).attr('name') ) {
var newid = $(clone).attr('name');
newid = newid.replace(/\[[0-9]*\]/, '[' + (counter + 1) + ']');
$(clone).attr('name', newid);
};

Categories