I am currently working on a C# project using ASP.NET. And I'd like to implement a list of dropboxes. So a User starts with a dropbox and can select a method and next to the dropbox is a + and - button, which enables a user to add more dropboxes. So I am wondering how can I implement that is it possible to build a List of dropboxes in ASP.NET?
You don't need any server side code for this, client side scripting is ideal solution for your needs.
Having such HTML:
<div id="MainPlaceholder">
<div id="DropDownPlaceholder">
<select name="myDropDown">
<option value="1">First</option>
<option value="2">Second</option>
<option value="3">Third</option>
</select>
<button type="button" onclick="AddDropDown(this);">+</button>
<button type="button" onclick="RemoveDropDown(this);">-</button>
</div>
</div>
You need the following pure JavaScript to make it work:
<script type="text/javascript">
var added_counter = 0;
function AddDropDown(sender) {
var parent = sender.parentNode;
//make fresh clone:
var oClone = parent.cloneNode(true);
//append to main placeholder:
parent.parentNode.appendChild(oClone);
//store change in global variable:
added_counter++;
}
function RemoveDropDown(sender) {
//don't allow to remove when there is only one left
if (added_counter <= 0) {
alert("One drop down must exist");
return;
}
var parent = sender.parentNode;
//disable so value won't be passed when form submitted:
parent.getElementsByTagName("select")[0].disabled = true;
//hide:
parent.style.display = "none";
//store change in global variable:
added_counter--;
}
</script>
The code has comments, but if you need any further explanation please feel free to ask.
Live test case.
Edit: As you need to read the selected values on the server side code, better approach would be to change the name of each cloned drop down:
var totalAddedCounter = 0;
function AddDropDown(sender) {
var parent = sender.parentNode;
//make fresh clone:
var oClone = parent.cloneNode(true);
//assign unique name:
oClone.getElementsByTagName("select")[0].name += "_" + totalAddedCounter;
//append to main placeholder:
parent.parentNode.appendChild(oClone);
//store change in global variable:
added_counter++;
totalAddedCounter++;
}
Now the tricky part is reading those values. Instead of plain dropboxlistID.Text you will have to iterate over all posted values looking for what you need:
foreach (string key in Request.Form.Keys)
{
if (key.StartsWith("dropboxlistID"))
{
string text = Request.Form[key];
//.....
}
Related
I have a controller in C# that, among other things, provides HTML for external links.
var htmlLinkBuilder = new StringBuilder($#"
<div>
<span>Dropdown</span>
</div>
<div class='dropdown-menu'>
");
foreach (var instance in thing.instances)
{
htmlLinkBuilder.AppendLine($#"
<a
class='dropdown-item'
href='{_configuration["Identity:Url"]}otherStuff/urlThings'
target='_blank'
rel='noopener noreferrer'
[onClickVar]
>
{instance.Name}
</a>
");
}
htmlLinkBuilder.AppendLine("</div>");
link.HtmlLink = htmlLinkBuilder.ToString();
I'm using dangerouslySetInnerHTML in a react js file which contains a handleNavClickLogging() function.
My question is, can I properly reference the function over each link with some form of
__html: htmlFromAbove.replaceAll("[onClickVar]", { () => handleNavClickLogging('External Link') } )
or how can I reference this function when clicking a dropdown item?
Expected output is an onclick function performed after clicking one of the dropdown items.
I'm trying to pull specific tag values on a page I created for experiment.I'm new to using Cefsharp. And I'm trying to experiment to improve myself.I was stuck for about two days in the EvaluateScriptAsync section.
I am trying to capture the values of the buttons in the specific label on the page I prepared.I run the following codes by pressing a button.My page has 3 buttons with the same label.However, it prints only one of them.
<input type="button" id ="button1" value="First Button">
<input type="button" id ="button2" value="Second Button">
<input type="button" id ="button3" value="Third Button">
These are the buttons I'm trying to find.
string script = #"(function() { " +
"var button = document.querySelectorAll('input[type = \"button\"]'); " +
"if(button != null) {for (var i = 0; i < button.length; i++) { return button[i].value;
}}else{alert('not found!');}" +
"})();";
chrome.EvaluateScriptAsync(script).ContinueWith(a =>{
var response = a.Result;
if (response.Success && response.Result != null)
{
string print = (string)response.Result;
MessageBox.Show(print.ToString());
}
}, TaskScheduler.FromCurrentSynchronizationContext());
I have tried many.I think I'm making a mistake in the javascript part.I've read most of the similar topics.But I could not find a solution.
output : First Button
This worked for me. The EvaluateScriptAsync funciton can only return 1 value or a string so I made sure to convert the results in JavaScript to a JSON string object.
Then when you retrieve the result back in C# land, you can then use JSON to convert it back to an object (in this case a list of strings) and perform any operations you need on the data.
// Step 01: Generate a HTML page
var htmlPage = #"
<html>
<body>
<p>Hello!!</p>
<input type='button' id='button1' value='First Button'>
<input type='button' id='button2' value='Second Button'>
<input type='button' id='button3' value='Third Button'>
</body>
</html>";
// Step 02: Load the Page
m_chromeBrowser.LoadHtml(htmlPage, "http://customrendering/");
// Step 03: Get list of buttons on page from C# land
var jsScript = #"
// define a temp function to retrieve button text
function tempFunction() {
var result = [];
var list = document.querySelectorAll('input[type=button]');
for(var i = 0, len = list.length; i < len; i++) {
result.push(list[i].value);
}
// Important: convert object to json string before returning to C#
return JSON.stringify(result);
}
// Now execute the temp function and returns result back to C#
tempFunction();";
var task = m_chromeBrowser.EvaluateScriptAsync(jsScript);
task.ContinueWith(t =>
{
if (!t.IsFaulted)
{
var response = t.Result;
if (response.Success == true)
{
// Use JSON.net to convert to object;
MessageBox.Show(response.Result.ToString());
}
}
}, TaskScheduler.FromCurrentSynchronizationContext());
Looking at your JavaScript code sample, the problem with your code is that in your loop you have a return statement that will just return the 1st button value it comes across. Thats your problem.
If you want to interact with the resulting list in C# land you will need to convert it back from a JSON string. Just go to nuget and install the 'Newtonsoft.Json' package into your project.
Then you can write something like:
// C# land
var list = new List<string>();
list = JsonConvert.DeserializeObject<List<string>>(response.Result.ToString());
I have an issue where between two pages I am sharing a modal, both pages are using the same angularJs version(v1.2.14), and both pages call the exact same directives (ui.select2). The select box inside of the modal works on one page, whilst on the other it simply stay as the default option.
As an fyi I have tried implementing the select box in different styles e.g. ng-repeat on the options, and not using the track by. This however results in the other pages selecting options to break. I can only ever get one page to work and the other to break.
The strange thing is that in the background the bound value is updating correctly:
<div class="col-md-10">
<select ui-select2="{width: '100%'}" class="form-control"
ng-model="Model.DocumentTypeId"
ng-options="documentType.DocumentTypeId as documentType.DocumentTypeDescription for documentType in Model.DocumentTypes track by documentType.DocumentTypeId">
<option value="">Select Document Type</option>
</select>
</div>
If you have any suggestions of why this is occurring it would be great.
Here is a heavily truncated view of the controller:
module Views.TMDocumentUpload {
export class DocumentUpload implements IDocumentUpload {
public static SetupDocumentUploadDialog = "onSetupDocumentUploadDialog";
public Init(model: DocumentUploadViewModel) {
var self = this;
if (self.$scope.Model.HideDocumentType || self.$scope.Model.DocumentTypeId == null) {
if (self.$scope.Model.DocumentTypes.length == 1) {
self.$scope.Model.DocumentTypeId = self.$scope.Model.DocumentTypes[0].DocumentTypeId;
}
}
}
constructor(public $scope: IDocumentUploadScope, $http: ng.IHttpService, $timeout: ng.ITimeoutService) {
$scope.isAllSelected = true;
$scope.ShareConfig = [];
$scope.Model.DisplayShareOptions = false;
$scope.Init = () => {
var self = this;
$scope.$on(DocumentUpload.SetupDocumentUploadDialog,
(e: ng.IAngularEvent, args?: Views.TMDocumentUpload.DocumentUploadViewModel) => {
self.$scope.Model = new DocumentUploadViewModel();
$http.get("/GetInitialModel")
.success(function (data: DocumentUploadViewModel) {
angular.extend(data, args);
self.Init(data);
});
});
};
}
}
DocumentUpload.$inject = ["$scope", "$http","$timeout"];
}
I have resolved the issue by removing ui-select2, it seems that this was causing some sort of conflict with another directive in my second page.
What I want to do is that I have created a asp.net web application and right now I m using XML to save my data (I AM NOT USING SQL)and my next task is to Generate A unique 8digits Alphanumeric Id for the users which will be used by them In future to track there request.
I have been given a particular format of this ID so I can't use 'GUID'.
The format given is this:
PR000000(PR stands for Project)
NP000000(NP stands for Non-Project)
So, the first two letters will be selected according to the user entry(if its a Project procurement request then 'PR' and in case of Non-project Procurement request 'NP') and rest 6 digits are simple integers which will keep increasing (000001,000002,000003....999999).
I have searched a lot everywhere but its all about php,uniquecode,GUID etc. but I just want a simple code which perform the above task with ease like IF-Else statement + keep increasing the count(000001...000002..).
This is the code for Project and Non project selection:
PROJECT<input type="radio" name="portal" id="radio1" onclick="changeMe(this);"/> <input type="text" name="textprojectOff" id="text1" value="Project Name" onclick="changeMe(this);"/>
NON-PROJECT<input type="radio" id="radio2" name="portal" onclick="changeMe(this)"/> <input type="text" name="textnonprojectOff" id="text2" value="Department" onclick="changeMe(this);"/>
<script type="text/javascript" >
function changeMe(inField)
{
var fieldId = inField.id;
var type = fieldId.substring(0, 4);
if (type == 'text') {
var name = fieldId.substring(4);
var radioButton = document.getElementById("radio" + name);
radioButton.checked = true;
} else {
var name = fieldId.substring(5);
var textField = document.getElementById("text" + name);
textField.focus();
textField.value ='';
}
}
If anyone require my xml code for my help then kindly tell me in the comment section I will post it at that time.
For your requirement, you will have to generate the unique ids from server-side code after checking the existing values in a Database.
you can use a Oracle Sequence if you want. Client side generation should not be used in this case because there is a change that multiple users can get the same unique id. So this generation should be handled server side / db side.
Here I got the solution of My Own problem ,So,I thought to share it with everyone so that other can get help from it. Without Using any typical Function I have generated an Unique Id for each and ever user.
.cs programming:
protected void GetId()
{
MSXML2.DOMDocument objXML = new MSXML2.DOMDocument();
string oPath = null;
oPath = Server.MapPath("PARNId.xml");
XmlDocument doc = new XmlDocument();
if (objXML.load(oPath) == true)
{
objNextId = objXML.selectSingleNode("//Id").text;
}
}
protected void SetId()
{
MSXML2.DOMDocument objXML = new MSXML2.DOMDocument();
string oPath = null;
oPath = Server.MapPath("PARNId.xml");
XmlDocument doc = new XmlDocument();
if (objXML.load(oPath) == true)
{
objXML.selectSingleNode("//Id").text = objNextId;
}
if (RadioButton2.Checked == true)
{
Label1.Text = "Your PURCHASE ACTION REQUEST NUMBER Is : PR" + objNextId;
}
else
{
Label1.Text = "Your PURCHASE ACTION REQUEST NUMBER Is :NP" + objNextId;
}
objXML.save(oPath);
}
Calling both the functions
GetId();
Label1.Text = objNextId;
objNextId = Convert.ToString(Convert.ToInt32(objNextId) + 1);
SetId()
I have created a separate XML file named Track.xml, in which I have assigned a node 100000,and this keep incrementing with every request made and finally I saved the label1.text and this keep record of all PARN generated with each user Hope it helps other!!
I am trying to write an application to automate router configuration. Unfortunately with the router we are using, telnet is not an option.
So I have had to interface with the Cisco web interface using C# WebClient class.
Up until now I had been able to set everything I needed using NameValueCollection and WebClient.UploadValues.
I would take all the input elements on the form, then just upload the name value Collection corresponding to the input types on the form, setting the values of each to the desired setting.
But now I have run into a problem.
With one of the forms, it is using a multiselect control to handle an array of input data, not an input type.
I am at a total loss for how to set this.
The html for the multiselect is as follows
<select multiple class="MultiSelect" name="PortRangeList" size="12" onChange="showList(this.form.PortRangeList);" style="width: 100%">
<option value="All Traffic{[(*-*-*)]}1;0;1;65535;0}">All Traffic [TCP&UDP/1~65535]</option>
<option value="DNS{[(*-*-*)]}2;17;53;53;0}">DNS [UDP/53~53]</option>
<option value="FTP{[(*-*-*)]}3;6;21;21;0}">FTP [TCP/21~21]</option>
...
</select>
When I was using the input types, I would simply do the following
NameValueCollection formNetworkData = new NameValueCollection();
formNetworkData["ipAddr"] = "192.168.1.2";
formNetworkData["lanMask"] = "255.255.255.0";
downloadedData = _routerWebClient.UploadValues(_routerIP + NETWORK, formNetworkData);
But looking at the code for this new form, it appears right before it submits, it selects all the options in the multiselect.
I realize I have probably asked this question poorely, but any assistance would be greatly appreciated.
Using Chrome debugger PortRangeList is exactly as you said.
There are 5 input types
submitStatus, upnpOpen (etc...)
For those my code looks like this
NameValueCollection formData = new NameValueCollection();
formData["submitStatus"]="1";
formData["upnpOpen"]="0";
downloadedData = _routerWebClient.UploadValues(SERVICE0, formData);
But in order to submit the PortRangeList data, I can't use the NameValueCollection because it does not allow a name to have muliple values.
how could submit that?
WebClient.UploadData, WebClient.UploadFile or WebClient.UploadString maybe?
Use Fiddler or Wireshark to compare what goes over the wire when it works ("normal" browser) and when it doesn't work (your code)... once you know the differences you can change your code accordingly...
You have to pass in the selected options by passing in the "PortRangeList" parameter multiple times, once for each option:
PortRangeList=All Traffic{[(*-*-*)]}1;0;1;65535;0}&PortRangeList=DNS{[(*-*-*)]}2;17;53;53;0}&PortRangeList=FTP{[(*-*-*)]}3;6;21;21;0}
That's how browsers do it. Since you're using the WebClient, try this:
PortRangeList=All Traffic{[(*-*-*)]}1;0;1;65535;0},DNS{[(*-*-*)]}2;17;53;53;0},FTP{[(*-*-*)]}3;6;21;21;0}
Obviously, everything has to be properly URL-escaped.
Thought I would post the final answer.
In the end I used the exact solution shown here.
http://anhonga.wordpress.com/2010/05/06/using-webclient-with-uploadvalues-and-uploadstring-to-simulate-post/
This is with his code, but I did essentially the exact same thing (without using global variables)
StringBuilder _strBld = new StringBuilder();
int _intItemCount = 0;
protected void btnSubmit_Click(object sender, EventArgs e)
{
System.Net.WebClient myWebClient = new System.Net.WebClient();
myWebClient.Headers.Add("Charset", "text/html; charset=UTF-8");
myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); // ◄ This line is essential
// Perform server-side validations (same as before)
if (this.F_Name.Text.Length == 0 || this.L_Name.Text.Length == 0)
{ AppendError("First and Last name must be provided"); }
…
// Add the user-provided name values
AppendUploadString("last_name", this.L_Name.Text);
AppendUploadString ("first_name", this.F_Name.Text);
AppendUploadString ("address", this.Address.Text);
// Add the Toppings
foreach (ListItem item in this.ToppingsChkBoxList.Items)
{
if (item.Selected)
{
AppendUploadString("Toppings", item.Value.ToString());
}
}
myWebClient.UploadString("https http://www.Destination.com/...?encoding=UTF-8", "POST", _strBld.ToString());
}
private void AppendUploadString(string strName, string strValue)
{
_intItemCount++;
_strBld.Append((intItemCount == 1 ? "" : "&") + strName + "=" + System.Web.HttpUtility.UrlEncode(strValue));
// Update: Use UrlEncode to ensure that the special characters are included in the submission
}