What i'm trying to do :
The working concept in JS :
In a basic form, i'm trying to reproduce this in a C# app
To clarify, user has to be able to choose how many parts there is (and name each part).
=> Example : My item has two parts, part_1 = "morning" and part_2 = "afternoon".
In order to reproduce that, i've done the following :
form.aspx :
<myform>
<asp:TextBox CssClass="form-control" runat="server" type="number" ID="parts_counter" />
<div id="content" runat="server"></div>
</myform>
=> Why : The value of parts_counter is then meant to be read and with a javascript block (i know...) i create the inputs dynamically
javascript_form.js :
let counter = document.getElementById('parts_counter');
let content = document.getElementById('content');
counter.addEventListener('change', function (e) {
if (counter.value == 0) {
content.innerHTML = "";
} else {
content.innerHTML = "";
for (let i = 0; i < counter.value; i++) {
content.innerHTML +=
"<input type='text' id='part_" + i + "' placeholder='Ex : Part name'/><br>";
// ---------------------^^^^^^^^^^^^
// THIS IS THE PART I WANT TO BE ABLE TO READ IN C # Codebehind
}
}
})
form.aspx.designer.cs :
protected global::System.Web.UI.WebControls.TextBox part_0;
protected global::System.Web.UI.WebControls.TextBox part_1;
protected global::System.Web.UI.WebControls.TextBox part_2;
protected global::System.Web.UI.WebControls.TextBox part_3;
protected global::System.Web.UI.WebControls.TextBox part_4;
=> Why : I tried to pre-register generated IDs, as there's no reason to have more than 5 parts in user scenario.
form.aspx.cs :
for (var i = 0; i < Convert.ToInt32(parts_counter.Text); i++)
{
var nomPartie = "partie_" + i;
var textBoxPartie = new TextBox();
textBoxPartie.ID = nomPartie;
// Do something for each
i++;
}
=> Why :
I read value of the counter,
I loop for each value to do a server-side action
I (over) looked at some solutions on CodeProject, SO, ASPSnippets and i'm sure i've thought of this the wrong way, could you please tell me if there is a specific way to generate inputs and to get their IDs afterwards in codebehind ?
Every pennies are welcome
Related
I apologize in advance, this is the first Stack Overflow question I've posted. I was tasked with creating a new ADA compliant website for my school district's technology helpdesk. I started with minimal knowledge of HTML and have been teaching myself through w3cschools. So here's my ordeal:
I need to create a page for all of our pdf and html guides. I'm trying to create a somewhat interactable menu that is very simple and will populate a link array from an onclick event, but the title="" text attribute drops everything after the first space and I've unsuccessfully tried using a replace() method since it's coming from an array and not static text.
I know I'm probably supposed to use an example, but my work day is coming to a close soon and I wanted to get this posted so I just copied a bit of my actual code.
So here's what's happening, in example 1 of var gmaildocAlt the tooltip will drop everything after Google, but will show the entire string properly with example 2. I was hoping to create a form input for the other helpdesk personnel to add links without knowing how to code, but was unable to resolve the issue of example 1 with a
var fix = gmaildocAlt.replace(/ /g, "&nb sp;")
//minus the space
//this also happens to break the entire function if I set it below the rest of the other variables
I'm sure there are a vast number of things I'm doing wrong, but I would really appreciate the smallest tip to make my tooltip display properly without requiring a replace method.
// GMAIL----------------------------
function gmailArray() {
var gmaildocLink = ['link1', 'link2'];
var gmaildocTitle = ["title1", "title2"];
var gmaildocAlt = ["Google Cheat Sheet For Gmail", "Google 10-Minute Training For Gmail"];
var gmailvidLink = [];
var gmailvidTitle = [];
var gmailvidAlt = [];
if (document.getElementById("gmailList").innerHTML == "") {
for (i = 0; i < gmaildocTitle.length; i++) {
arrayGmail = "" + gmaildocTitle[i] + "" + "<br>";
document.getElementById("gmailList").innerHTML += arrayGmail;
}
for (i = 0; i < gmailvidTitle.length; i++) {
arrayGmail1 = "";
document.getElementById("").innerHTML += arrayGmail1;
}
} else {
document.getElementById("gmailList").innerHTML = "";
}
}
<div class="fixed1">
<p id="gmail" onclick="gmailArray()" class="gl">Gmail</p>
<ul id="gmailList"></ul>
<p id="calendar" onclick="calendarArray()" class="gl">Calendar</p>
<ul id="calendarList"></ul>
</div>
Building HTML manually with strings can cause issues like this. It's better to build them one step at a time, and let the framework handle quoting and special characters - if you're using jQuery, it could be:
var $link = jQuery("<a></a>")
.attr("href", gmaildocLink[i])
.attr("title", gmaildocAlt[i])
.html(gmaildocTitle[i]);
jQuery("#gmailList").append($link).append("<br>");
Without jQuery, something like:
var link = document.createElement("a");
link.setAttribute("href", gmaildocLink[i]);
link.setAttribute("title", gmaildocAlt[i]);
link.innerHTML = gmaildocTitle[i];
document.getElementById("gmailList").innerHTML += link.outerHTML + "<br>";
If it matters to your audience, setAttribute doesn't work in IE7, and you have to access the attributes as properties of the element: link.href = "something";.
If you add ' to either side of the variable strings then it will ensure that the whole value is read as a single string. Initially, it was assuming that the space was exiting the Title attribute.
Hope the below helps!
UPDATE: If you're worried about using apostrophes in the title strings, you can use " by escaping them using a . This forces JS to read it as a character and not as part of the code structure. See the example below.
Thanks for pointing this one out guys! Sloppy code on my part.
// GMAIL----------------------------
function gmailArray() {
var gmaildocLink = ['link1', 'link2'];
var gmaildocTitle = ["title1", "title2"];
var gmaildocAlt = ["Google's Cheat Sheet For Gmail", "Google 10-Minute Training For Gmail"];
var gmailvidLink = [];
var gmailvidTitle = [];
var gmailvidAlt = [];
if (document.getElementById("gmailList").innerHTML == "") {
for (i = 0; i < gmaildocTitle.length; i++) {
var arrayGmail = "" + gmaildocTitle[i] + "" + "<br>";
document.getElementById("gmailList").innerHTML += arrayGmail;
}
for (var i = 0; i < gmailvidTitle.length; i++) {
var arrayGmail1 = "";
document.getElementById("").innerHTML += arrayGmail1;
}
} else {
document.getElementById("gmailList").innerHTML = "";
}
}
<div class="fixed1">
<p id="gmail" onclick="gmailArray()" class="gl">Gmail</p>
<ul id="gmailList"></ul>
<p id="calendar" onclick="calendarArray()" class="gl">Calendar</p>
<ul id="calendarList"></ul>
</div>
I'm using ASP to look for the selected value in a dropdown box. The dropdown box choices are generated at load time. Here is the JavaScript for that:
function CreateDepartmentDropdown(data) {
var dropdown = document.getElementById("department_dropdown");
for (var i = 0; i < data.length; i++) {
var array = data[i].split(',');
var option = document.createElement("option");
option.value = array[0];
option.innerHTML = array[1];
dropdown.add(option);
}
}
And it looks like this:
Looks fine to me. Then I checked the HTML out too just to be sure:
That looks great too. Now here is where the issue comes up. When I press submit this delegate fires in C# (still only testing while making this):
void Activity_Submit_Click(object sender, EventArgs e)
{
int fye = Int32.Parse(fye_dropdown.Value);
String activity_name = activity_name_field.Value;
String activity_responsible = responsible_field.Value;
int department = Int32.Parse(department_dropdown.Value);
String activity_start = datepicker_start.Value;
String activity_end = datepicker_end.Value;
}
And when I debug this it stops at department saying that it's malformed. Looking at department_dropdown.Value in the immediate window turns up an empty string and the dropdown itself has 0 children.
Why would this return an empty response when the list is clearly there? How would I go about fixing this?
The client-side items won't get posted back to the server like this.
The easiest way is to Serialize the array as Json, put it in a hidden input element's value :
In your markup:
<asp:HiddenField runat="Server" ID="department_dropdown_items" cssclass="department_dropdown_items" />
<asp:HiddenField runat="Server" ID="department_dropdown_selected" cssclass="department_dropdown_selected" />
Your Javascript:
function CreateDepartmentDropdown(data) {
var dropdown = document.getElementById("department_dropdown");
for (var i = 0; i < data.length; i++) {
var array = data[i].split(',');
var option = document.createElement("option");
option.value = array[0];
option.innerHTML = array[1];
dropdown.add(option);
}
$(".department_dropdown_items").text(JSON.Stringify(data));
}
$(document).ready(function() {
$("form").submit(function(e) {
$(".department_dropdown_selected").text( $("#department_dropdown").value);
});
});
then use it in the code behind:
void Activity_Submit_Click(object sender, EventArgs e)
{
string[] data = new JavascriptSerializer().Deserialize<string[]>(department_dropdown_items.Value);
string selectedValue = department_dropdown_selected.Value;
int fye = Int32.Parse(fye_dropdown.Value);
String activity_name = activity_name_field.Value;
String activity_responsible = responsible_field.Value;
int department = Int32.Parse(department_dropdown.Value);
String activity_start = datepicker_start.Value;
String activity_end = datepicker_end.Value;
}
The code is not tested. Tell me if it's not working :)
So I ended up doing the following:
Make a Hidden asp element called department_dropdown_selected_value
Then in a Script tag I made the following function:
.
function GetDepartmentDropdownValue(sel) {
var hidden_field = document.getElementById('department_dropdown_selected_value');
hidden_field.value = sel.value;
}
Then in my HTML I did this: <select class="form-control" id="department_dropdown" onchange="GetDepartmentDropdownValue(this)">
Then I can just simply do this in C#: int department = Int32.Parse(department_dropdown_selected_value.Value);
I am trying to generate a table of data from a JSON file using Javascript but am having difficulty because of the bean:write tag. The bean: is getting removed, so only <write name="offenderCountVO" property="addressCount"/> seems to be getting parsed. Is this approach even feasible?
From the page that generates the table:
// Build profile section from JSON file
$.getJSON('<%=request.getContextPath()%>/jsp/json/offenderProfileJSON.jsp', function(data) {
//alert('loading JSON');
var items = [];
var table = $('<table class="profile"><\/table>');
var profileCols = 2;
var td = "";
// Build array of profile categories
for (i = 0; i < data.length; i++) {
//alert("building items");
// Check if this category can be displayed in this module
var item = data[i];
var modules = item["modules"];
//alert("Start check");
if (modules.indexOf(appName) > 0) {
// This category should be displayed
//alert ("Passed");
var label = item["label"];
var link = item["link"];
var name = item["name"];
var property = item["property"];
newCategory = { label: label, modules: modules, link: link, name: name, property: property };
items.push(newCategory);
}
}
// Alphabetically sort categories by label
//alert(items.length);
for (i = 0; i < items.length; i++) {
html = '<tr><td><a href="<%=request.getContextPath()%>/' + items[i].link + '">'
+ items[i].label + '</a></td><td>\u003Cbean\u003Awrite name="'
+ items[i].name + '" property="' + items[i].property + '" /\u003E</td></tr>';
}
$("#testArea").html(html);
//table.appendTo("#testArea");
alert("Done");
}).error(function() {
$("#testArea").html('<span class="error">Error parsing JSON.</span>');
});
The JSON file:
[
{
"label" : "Address",
"modules" : "AGNT,BOOKING,DIO,OMP,OTA",
"link" : "offenderAddress.do?method=list",
"name" : "offenderCountVO",
"property" : "addressCount"
},
{
"label" : "Assessments",
"modules" : "AGNT,BOPP,OMP,OTA",
"link" : "offenderAssessmentList.do?method=list",
"name" : "offenderCountVO",
"property" : "assessmentCount"
}
]
I hope I've explained the issue well enough -- I'm working on several different projects and my head is spinning right now, so let me know if you need any clarification. Any guidance would be appreciated.
<bean:write> is a tag understood by JSP on the server-side, at the point when the initial page is created.
Using:
'<td>\u003Cbean\u003Awrite name="'+ items[i].name + '" property="' + items[i].property + '" /\u003E</td>'
from JavaScript makes no sense because the web browser that includes the resultant <bean:write> tag in its page DOM doesn't know anything about Java or bean tags. When the browser's HTML parser sees <bean:write> it thinks only "that's some write tag that I don't know about, spelled funny" and not "I had better ask the server-side what it's value for the property of that bean is".
If you want the browser to see the server-side value of a variable, you must return that value itself in the JSON response to the browser, not just a name and value pair that only mean anything to the bean-based server side.
Note also that dropping unescaped strings into HTML markup is dangerous. Without HTML-escaping, you have cross-site-scripting security holes when any of the item values may contain user-submitted values. Use DOM-property methods to set element text and attribute values instead of trying to create HTML markup strings from JavaScript. eg:
<input type="hidden" id="contextPath" value="<c:out value="${pageContext.request.contextPath}"/>"/>
...
var cp = document.getElementById('contextPath').value;
for (var i= 0; i<items.length; i++) {
table.append(
$('<tr>').append(
$('<td>').append(
$('<a>', {href: cp+'/'+items[i].link, text: items[i].label})
)
).append(
$('<td>', {text: items[i].value_of_whichever_property_it_is})
)
);
}
I have a report populated as a table with a stringbuilder from the codebehind. The first TD of every row is a checkbox, the id of each checkbox is assigned dynamically:
sb.Append("<td><input type='checkbox' id='chkSelectAll_" + i + "' name='chk_" + i + "' onclick='JavaScript: chkAll_click(this);' /> </td>"
The aspx page uses a master page and
<asp:Content><div id='divMain'></div></asp:Content>
format other than a form to populate. The problem I am running in to is that I am having trouble finding all the elements (or any actually) of the div to work with. Here is the javascript I have been given. (Team project at work, I was just assigned 1 task on the project so changing anything is not an option.)
function divBatchBuild_click() {
debugger
var form = document.forms[0];
var visitList = '';
for (i = 0; i < form.elements.length; i++) {
if (form.elements[i].type == 'checkbox') {
//alert(form.elements[i].id.toString());
if (form.elements[i].checked == true &&
form.elements[i].id != 'chkSelectAll') {
var y = form.elements[i].id;
//alert('id=' + y[1].toString());
visitList = visitList + y[i].toString() + '|';
}
}
}
}
Apparently this worked on a previous project, but when used with this report the process never goes inside the if statement. Any help on what is going wrong is appreciated.
I think you want to first get the div, then get the elements in the div with the checkbox tagname. Something like:
var div = document.getElementById('divMain');
var elements = div.getElementsByTagName('checkbox');
for (i = 0; i < elements.length; i++) {
I'm writing a custom javascript validation script whereby i iterate through all input elements in a div named 'toggle' and select each that has a class named 'required' and if the value of the element is an empty string (empty) then i need to create labels containing the error message and place them right next to the textbox.
Here's the code:
function clientErrMsgs() {
var container = document.getElementById("toggle");
var inputArray = container.getElementsByTagName("input");
for (var i = 0; i < inputArray.length; i++) {
alert("");
if (inputArray[i].getAttribute("class") == "required" && inputArray[i].value == "") {
var errmsg = inputArray[i].getAttribute("data-errormessage");
var labelErr = document.CreateElement('label');
labelErr.id = "ErrMsg" + i;
labelErr.value = errmsg;
var parent = inputArray[i].parentNode;
parent.appendChild(labelErr);
}
}
}
the program executes well (tested it with alert()) up until the following line:
var labelErr = document.CreateElement('label');
Where is the problem?
you can use asp.net custom validator to do this
i am giving you an example, how to do this....
<asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="Sms length is exceeding over 160."
ClientValidationFunction="validateLength" ControlToValidate="txtSmsMessage"
SetFocusOnError="True" ValidationGroup="add">*</asp:CustomValidator>
<script language="javascript" type="text/javascript">
function validateLength(oSrc, args)
{
args.IsValid = (args.Value.length < 160);
}
</script>
i suggest please try this...
I got things working with:
http://jsfiddle.net/ahallicks/kxPeN/2/
labels don't have a value attribute
Its document.createElement not document.CreateElement
MDC link : document.createElement
Update: you should access the innerHTML of the label and not the value
The snippet
var labelErr = document.createElement('label');
labelErr.id = "ErrMsg" + i;
labelErr.innerHTML= errmsg;
var parent = inputArray[i].parentNode;
parent.appendChild(labelErr);
This is not a direct answer to your question, but would your superior go for a different pre-built validation method? I'm partial to FlowPlayers jQuery based validator. Very simple to setup:
$("#myform").validator();
I've written several validation frameworks in the past. I finally got tired of reinventing the wheel.
May I suggest this:
function clientErrMsgs() {
var container = document.getElementById("toggle");
var inputArray = container.getElementsByTagName("input");
for (var inp, i=0, n=inputArray.length; i<n; i++) {
inp = inputArray[i];
if (inp.getAttribute("class") === "required") {
var errMsg = container.getElementById("ErrMsg"+i);
if (!errMsg) {
errMsg = document.createElement('span');
errMsg.id = "ErrMsg" + i;
errMsg.innerHTML= inp.getAttribute("data-errormessage");
inp.parentNode.appendChild(errMsg);
}
errMsg.style.display= (inp.value === "")?"":"none"
}
}
}