I want to display a colorpicker on an MVC5 application. This feature works if manually typed out and adapted for each page that uses it. Obviously, this is excessively duplicated code so I created a Utils method to generate the data. Here is the definition for that method:
public static string GetColorsList()
{
string colorsList = "<option style=\"color:gray\" value=\"null\">select color</option>" +
"<option style=\"color:azure\" value=\"Azure\">Azure</option>" +
"<option style=\"color:blue\" value=\"Blue\">Blue</option>" +
"<option style=\"color:cyan\" value=\"Cyan\">Cyan</option>" +
"<option style=\"color:green\" value=\"Green\">Green</option>" +
"<option style=\"color:magenta\" value=\"Magenta\">Magenta</option>" +
"<option style=\"color:orange\" value=\"Orange\">Orange</option>" +
"<option style=\"color:red\" value=\"Red\">Red</option>" +
"<option style=\"color:violet\" value=\"Violet\">Violet</option>" +
"<option style=\"color:yellow\" value=\"Yellow\">Yellow</option>";
return colorsList;
}
The reason I return a string instead of an IEnumerable is that a JS method adds new data (i.e. create a new row in the table) to the page using:
$(#tablename tbody).append(newcontent);
where new content is a string of the HTML to insert. Ideally I could just create an Html.DropDownList to display the picker contents but this does not return a string-friendly result.
What I want to accomplish: take colorsList, put in in ViewData["x"], turn ViewData["x"] into a string, and concat that string with other content that belongs in newcontent.
ViewData["x"].ToString() yields the following result:
<option style="color:gray" value="null">select
color</option><option style="color:azure" value="
Azure">Azure</option><option style=
"color:blue"
value="Blue">Blue</option><option style="
color:cyan" value="Cyan">Cyan</option><
option style="color:green" value="Green">
Green</option><option style="color:magenta" value=
"Magenta">Magenta</option><option style=
"color:orange" value="Orange">Orange</option
><option style="color:red" value="Red">
Red</option><option style="color:violet" value=
"Violet">Violet</option><option style=
"color:yellow" value="Yellow">Yellow</option>);
The workaround here is to run:
colorpickerContent = colorpickerContent.replace("$lt;", "<");
colorpickerContent = colorpickerContent.replace("$gt;", ">");
colorpickerContent = colorpickerContent.replace(""", "\"");
So that all the proper characters exist. When running, the program throws a syntax error because the output does not start with the quotation marks needed to consider it a string. Any suggestions on how I can make ViewData["x"] a workable string? I attempted JSON.stringify() but found similar results.
You're looking for the HtmlString that one won't be escaped.
Related
I have a table in HTML where the ID is dynamically generated from a row counter:
$(table).find('tbody').append("<tr>name=\"tableRow\"</tr>"
+ "<td>"
+ "<select id=\"shapeSelect_" + rowCount + "></td>"
+ "<option onclick=\"sphereSelect()\" value=\"sphere\">Sphere</option>"
+ "<option onclick=\"cylinderSelect()\" value=\"cylinder\">Cylinder</option>"
+ "</select>"
+ "</td>"
+ "<td><input type=\"text\" id=\"altitude" + rowCount + "\"</td>"
+ "<td><input type=\"text\" name=\"maxAlt\" id=\"maxAltitude_" + rowCount + "></td>"
+ "</tr>"
I need maxAltitude to become disabled for input when sphere is selected. When cylinder is selected, it should become enabled for input.
Every example I find is pretty simple but requires knowing exactly what the ID is, where in my code it is dynamically generated. This is an example of what I'm finding:
$(#maxAltitude).prop("disabled", true);
How can I do this when maxAltitude will be something more like: maxAltitude_10? There may be 1-n rows in a table, and I need to specifically disable the max altitude in the row where the dropdown select was changed.
I've tried jQuery and javascript but can't seem to find a good way to do this:
<option onclick="shapeSelect()" value="sphere">Sphere</option>
<option onclick="shapeSelect()" value="cylinder">Cylinder</option>
function shapeSelect() {
var shapeSelects = document.getElementsByName("shapeSelect");
var maxAlts = document.getElementsByName("maxAlt");
for(var i = 0; i < shapeSelects.length; i++) {
switch(shapeSelects[i].value) {
case "sphere":
maxAlts[I].disabled = True;
break;
case "cylinder":
maxAlts[i].disabled = False;
}
}
}
With the above code I get: SyntaxError: unexpected token: identifier whenever shapeSelect() is fired.
I've modified the code as follows:
<table class="myTable" id="myTable"></table>
$(table).find('tbody').append("<tr>name=\"tableRow\"</tr>"
+ "<td>"
+ "<select id=\"shapeSelect_" + rowCount + "></td>"
+ "<option value=\"sphere\">Sphere</option>"
+ "<option value=\"cylinder\">Cylinder</option>"
+ "</select>"
+ "</td>"
+ "<td><input type=\"text\" id=\"altitude_" + rowCount + "\"</td>"
+ "<td><input class=\"maxAltitudeInput\" type=\"text\" id=\"maxAltitude_" + rowCount + "\" disabled></td>"
+ "</tr>"
$('#myTable').on('change','.shapeSelector',function(){
var shouldDisableInput = $(this).val() === 'sphere';
$(this).closest('tr').find('.maxAltitudeInput').attr('disabled',shouldDisableInput);
}
And still nothing happens when I change the shape selector dropdown.
EDIT:
Apologies on the naming mismatches. My dev machine is on an airgapped network and I was hand jamming the post here on Stack Overflow. The rowCount variable was being created and incremented in another function. I was trying to only put relevant code in the post for brevity.
I was missing a class from shapeSelector. That was the missing link. It works now!
jQuery actually makes this really easy by binding this to whichever element triggered an event.
For instance, instead of writing a generic function for when that value changes, you could use jQuery to bind an event listener to them:
$('#myTable').on('change','.shapeSelector',function(){
var shouldDisableInput = $(this).val() === 'sphere';
$(this).closest('tr').find('.maxAltitudeInput').attr('disabled',shouldDisableInput);
}
You'll notice a few things in this snippet:
The element we are binding the listener to is the table, not the individual row. That's because the row is dynamic, and we don't want to have to keep adding listeners every time we add a row. Instead we add it to the parent which is stable, but then we specify that we are interested in its children that match ".shapeSelector"
The listener relies on class names, not IDs, since we want to match multiple copies of them, not just a specific one. So you'd need to add those class names or a similar way of matching more than one item
Inside the callback function that runs, you'll notice a couple uses of this. jQuery has bound that to the element that triggered the event listener, in this case, the <select> control. So when we use this, we have to think of it from that perspective. We can get its value by $(this).val(), we can find its parentt with $(this).parent(), etc. In this case, I'm travelling up to the nearest tr, then from there down to that tr's input that I want to disable. You'd need to adjust a little depending on your dom.
Also note that this is a DOM element, not a jQuery result. That's why when we want to run more jQuery commands on it, we have to put it in $() again.
That's how I'd approach it. We don't have your entire code here, so you'll have to adjust a bit, but hopefully that pushes you off in the right direction.
EDIT
To be honest, there were a lot of naming mismatches and things that didn't line up. For instance, you were attempting to append onto a tbody tag, but that tag didn't exist. You were using a rowCount variable, but didn' ever set that up or increment it. The select tag sill didn't have the class name you were trying to use.
I suggest you look at your code piece by piece, ask yourself what you're telling the browser to do, and then do that instruction in your mind to make sure the computer can do it.
HTML:
<table class="myTable" id="myTable"><tbody></tbody></table>
JavaScript:
var rowCount = 0;
function addRow(){
$('.myTable tbody').append(`<tr name="tableRow">
<td>
<select class="shapeSelector" id="shapeSelect_${rowCount}">
<option value="sphere">Sphere</option>
<option value="cylinder">Cylinder</option>
</select>
</td>
<td><input type="text" id="altitude_${rowCount}" /></td>
<td><input class="maxAltitudeInput" type="text" id="maxAltitude_${rowCount}" disabled></td>"
</tr>`);
rowCount++;
}
$('.myTable').on('change','.shapeSelector',function(){
var shouldDisableInput = $(this).val() === 'sphere';
$(this).closest('tr').find('.maxAltitudeInput').attr('disabled',shouldDisableInput);
});
addRow();
addRow();
addRow();
https://jsfiddle.net/32vnjq81/
I am having trouble appending a lot of html.
This is what I have:
$("#popup1").click(function(){
$(".cd-popup-container").append("<p>Are you sure you want to decline this employement request?</p>");
$(".cd-popup-container").append("<form id='accept_employe' action='/accept_employe' method='post' accept-charset='utf-8'>");
$(".cd-popup-container").append("<ul class='cd-buttons no_margin'>");
$(".cd-popup-container").append("<li><a class='submit'>Yes</a></li>");
$(".cd-popup-container").append("<li><a class='popup-close'>No</a></li>");
$(".cd-popup-container").append("</ul>");
$(".cd-popup-container").append("</form>");
$(".cd-popup-container").append("<a class=cd-popup-close popup-close img-replace>Close</a>");
});
Obviously many appends will not work as it will only get the first one. However, when I put it all on the same line it doesn't work either.
How can I clearly append all this html into the .cd-popup-container?
Yea, you can (and should) definitely make it cleaner and easier to maintain. For example with array of strings and join by empty string:
$("#popup1").click(function() {
var html = [
"<p>Are you sure you want to decline this employement request?</p>",
"<form id='accept_employe' action='/accept_employe' method='post' accept-charset='utf-8'>",
"<ul class='cd-buttons no_margin'>",
"<li><a class='submit'>Yes</a></li>",
"<li><a class='popup-close'>No</a></li>",
"</ul>",
"</form>",
"<a class=cd-popup-close popup-close img-replace>Close</a>"
].join('');
$(".cd-popup-container").append(html);
});
And of course, it doesn't matter what approach you will take, the one I posted or more traditional with string concatenation, - the important part is that you don't perform many repetitive DOM appends, but rather combine them in bulks.
You can use a single append function by adding a + to the end of each line(except for the last line):
$("#popup1").click(function(){
$(".cd-popup-container").append(
"<p>Are you sure you want to decline this employement request?</p>" +
"<form id='accept_employe' action='/accept_employe' method='post' accept-charset='utf-8'>" +
"<ul class='cd-buttons no_margin'>" +
"<li><a class='submit'>Yes</a></li>" +
"<li><a class='popup-close'>No</a></li>" +
"</ul>" +
"</form>" +
"<a class=cd-popup-close popup-close img-replace>Close</a>"
);
});
JSFiddle
Please help me to solve this string formating . it shows error while running.
I need to call a java script function AddHotel() with some php variables from an input tag. while running the first parameter in function shows error. It should be like onClick='AddHotel('divid', 'some_id', 'id',ids,rate)'
but while running in comes as onClick='AddHotel(divid', 'some_id', 'id',ids,rate)'
$resort[] = "<div id='".$iiiddd."'><input id='hotel_day".$child_post->ID.$dyid."' name='hotel_day".$dyid."' type='radio' value='".$child_post->ID."' onclick='AddHotel(".$p.",'".$s."','".$psid."','".$dyid."','".$child_post->ID."',".$child_post->fields['price'].")' />
<input id='".$s."' name='expsel".$dyid."[]' type='hidden' value='' />".$child_post->post_title."<span>Rs:- ".$child_post->fields['price']."</span></div>";
You want to escape Quotes
$resort[] = "<div id='".$iiiddd."'><input id='hotel_day".$child_post->ID.$dyid."' name='hotel_day".$dyid."' type='radio' value='".$child_post->ID."' onclick='AddHotel(".$p.",\'".$s."\',\'".$psid."\',\'".$dyid."\',\'".$child_post->ID."\',".$child_post->fields['price'].")' />".$child_post->post_title."Rs:- ".$child_post->fields['price']."";
For all who face such issues:
You should always use Double quotes for HTML attributes value eg:
<div attribute="value"><div>
For passing variables in a Javascript functions, you must use quotes (single quote preferably) for string. eg:
somethingAwesome('work', 'life', 1);
While embedding HTML and Javascript in PHP, you must not get confused with Quotes.
PHP string + HTML element:
$string = '<div></div>';
PHP string + HTML element with attributes:
$string = '<div id="awesome"></div>';
PHP string + HTML element with attributes + Javascript Function:
$string = '<div id="awesome" onclick="somethingAwesome()"></div>';
PHP string + HTML element with attributes + Javascript Function with Parameters:
$string = '<div id="awesome" onclick="somethingAwesome(\''.$string.'\', \''.$string2.'\', '.$integer.');"></div>';
You are open to choose double or single quotes, but following one particular fashion will prevent you from getting confused.
Also remember to Indent your code even in case of HTML in strings
Solution for your issue:
$resort[] = '<div id="'.$iiiddd.'">
<input id="hotel_day'.$child_post->ID.$dyid.'" name="hotel_day'.$dyid.'" type="radio" value="'.$child_post->ID.'" onclick="AddHotel(\''.$p.'\', \''.$s.'\', '.$psid.', \''.$dyid.'\', '.$child_post->ID.', \''.$child_post->fields['price'].'\')" />
<input id="'.$s.'" name="expsel'.$dyid.'[]" type="hidden" value="" />
'.$child_post->post_title.'
<span>Rs:- '.$child_post->fields['price'].'</span>
</div>';
I am a beginner to javascript ! I am trying to call a function from another function inside the same script tags. When I do this without sending arguments it works fine but when i do that with arguments that another function is not called..
Here is what I am doing
function measurement_convert()
{
var mc = "Measurement Conversion";
txt = "<h2>" + mc + "</h2> <br><br>";
txt +=
"<form action='' method='post'>" +
"Select Type <select name='conversion_type' onchange='loadXML('abcd')'> "+
"<option value='area'>Area</option>"+
"<option value='length'>Length</option>"+
"<option value='volume'>Volume</option>"+
"<option value='weight'>Weight</option>"+
"</select> <br><br>"
document.getElementById("content_main_top").innerHTML=txt;
}
So, I am calling the function from onchange of this form.
And here's the another function
function loadXML(var1)
{
document.getElementById("content_main_top").innerHTML=null;
document.getElementById("content_main_bottom").innerHTML=null;
}
Can anyone help me ?
Your problem is that you are trying to nest the same type of quote:
onchange='loadXML('abcd')'
This actually gets interpreted as:
onchange='loadXML('
Instead, try (note the escaped double-quotes, since this code is inside a PHP string):
Select Type <select name=\"conversion_type\" onchange=\"loadXML('abcd')\">
Your single quotes are clashing in the onchange value, as you use the same for closing the value in.
You can change it to:
"Select Type <select name='conversion_type' onchange=\"loadXML('abcd')\"> "
How do i fix this link in javascript.
Link
Its missing single quotes around 'Business'
Javascript:
html += "<option value='javascript:clientGalleryLink(" + titleArray[x] + ")'>" + titleArray[x] + "</option>";
use \ to escape the quotes
html += "<option value='javascript:clientGalleryLink(\"" + titleArray[x] + "\")'>" + titleArray[x] + "</option>";
<a href='javascript:clientGalleryLink("Business")'>Link</a>
html += "<option value='javascript:clientGalleryLink(\"" + titleArray[x] + "\")'>" + titleArray[x] + "</option>";
Could you please try this one out.
Thanks.
Try this to escape the attribute quotes and thus giving you the single inner quotes like you show in your example.
html += "<option value=\"javascript:clientGalleryLink('" + titleArray[x] + "')\">" + titleArray[x] + "</option>";
Escaping problems like this is why it's best to avoid creating JavaScript-in-HTML dynamically in strings. The javascript: pseudo-URL scheme should also never be used.
Instead, consider an ‘unobtrusive scripting’ approach: move the data out of an embedded JS string and into normal attributes, such as class or, if the link corresponds to a particular element on the page, the href itself:
<a class="gallerylink" href="#Business">Link</a>
for (var i= document.links.length; i-->0;) {
if (document.links[i].className==='gallerylink') {
document.links[i].onclick= function() {
clientGalleryLink(this.hash.substring(1));
return false;
};
}
}
The second example:
html += "<option value='javascript:clientGalleryLink(" + titleArray[x] + ")'>" + titleArray[x] + "</option>";
is just a mess. Aside from the lack of \' quoting around the titleArray value, and the lack of HTML-escaping or JS-string-literal-escaping on the titleArrays (so if you have '"<& characters in the title you've got problems).
Are you expecting the script to get executed when the option is chosen just because you've put it in the value? It won't.
Better to use the DOM objects than trying to mess around inserting JavaScript inside HTML inside JavaScript inside HTML. For example, if you're looking for a select box that calls clientGalleryLink every time the selected option is changed:
<div id="PlaceWhereYouWantToPutTheSelectBox"></div>
<script type="text/javascript">
var s= document.createElement('select');
for (var i= 0; i<titleArray.length; i++) {
s.options[i]= new Option(titleArray[i], titleArray[i]);
}
s.onchange= function() {
clientGalleryLink(this.options[this.selectedIndex].value);
};
document.getElementById('PlaceWhereYouWantToPutTheSelectBox').appendChild(s);
</script>
No ugly escaping necessary, no cross-site-scripting security holes.
add slashes:
\"" + titleArray[x] + "\"