So currently I have a drop down menu that is populated with a json file with each option looking like such (there are many more sets in the actual file) :
JSON
{
"thing": {
"Selected thing": [
{
"name" : "thing 1",
"value" : 1.0,
"purpose": "thing 1"
},
]
}
}
They are being populated into the below HTML select with a script:
HTML
<tr>
<td><strong>Choose a Thing</strong></td>
<td>
<div>
<select name="thing" class="form-control" id="thing" value="{{ thing }}">
<option class ="placeholder">{{ thing }}</option>
</select>
</div>
</td>
</tr>
JavaScript
$(document).ready(function () {
var menu = document.getElementById('thing')
$.getJSON("{{ url_for('static', filename='things.json') }}", function (data) {
$.each(data.things, function (optgroup, options) {
var next_optgroup = document.createElement('OPTGROUP')
next_optgroup.setAttribute("label", optgroup)
menu.appendChild(next_optgroup)
$.each(options, function (index) {
next_option = document.createElement('OPTION')
next_option.setAttribute("value", options[index].value)
next_option.setAttribute("name", options[index].name)
next_option.innerHTML = options[index].name
next_optgroup.appendChild(next_option)
});
});
});
})
So currently, once the selected option is chosen and a submit button is pressed, the value (1) is passed to Flask and stored and rendered to the select options value via {{ thing }}.
I need it to function as it does, but I also need to be able to store the name that is associated with the selected option which I feel I may need to use javascript or some hidden inputs (definitely place another input on my HTML form) to do this, though my knowledge of javascript is minimal.
In other words, how would I be able to store and upon a refresh of the page, keep the selected options name (thing 1) displayed on the HTML page?
Local Storage (https://www.w3schools.com/html/html5_webstorage.asp) described in the link can be used to store data in the User's browser on their local machine. This means that if they visit the page from a different computer, they will not be able to access that stored data. If you need to persist this information and access it from different machines/browsers, then you will have to implement a Database on a live web server and request this information when the user hits the page.
Local Storage is simple to use. Here is an example of how to set the a variable for the User's selected thing:
// Using jQuery
$('#thing').on('change', function() {
// Save the Value in local storage
localStorage.setItem('userThing', $('#thing').val());
});
To load the value from storage after the page is ready AND you have built and populated the 'thing' select form element:
// Get the 'userThing' from local storage and set the select element with id 'thing'
$('#thing').val(localStorage.getItem('userThing');
These task is vary common for Javascript developers. Frameworks such as Google's AngularJS and Facebook's React have been built to simplify these tasks (That is they are very simple to do after you have learned the framework...which will take a little while to feel comfortable using but well worth the effort if you intend to build large projects using javascript). They rely heavily on the MVC paradigm which is strongly recommend in developing Web Applications.
Related
I have a web application using Umbraco (MVC .NET) that has (for now) only two roots. They are named "English" and "Swedish". English is the default webpage and Swedish should be optional for the user. In order for the user to be able to change language I display them in a dropdown menu using Razor:
#{
List<SelectListItem> languages= new List<SelectListItem>();
foreach (var language in Model.Content.Siblings())
{
languages.Add(new SelectListItem
{
Text = language.Name,
Value = language.Url
});
}
#Html.DropDownList("LanguageSelect",new SelectList(languages,"Value","Text"), htmlAttributes: new { id = "LanguageSelect" });
}
This properly outputs the names of the roots at root level. Now using javascript i reroute using onchange:
document.getElementById("LanguageSelect").onchange = function() {
window.location.href = this.value;
};
This works for going from one language to another. Now the hard part starts: because this dropdown exists in my master template inherited by all views, when a new view is loaded, everything from the template is reloaded. Therefor the dropdown is reloaded and the selected language is lost in the dropdown. Instead of looking at the URL for which value should be set in the dropdown I wanted to use local storage. So I tried setting this in the onchange function for the dropdown:
localStorage.setItem("LanguageSelectStoredUrl", this.value);
But this saves the URL. I would like to save the text aswell, i.e. "Swedish" and just set the current value of the dropdown to the stored value. This should work, right? If so how do I do that? Any reasons not to?
Another reason why I wanted to do it this way is because I want the user in a later session not having to choose language again by using:
$(document).onload(function(){
if(localStorage.getItem("LanguageSelectStoredValue") != null){
// Check if the dropdown value is equal to the stored value
// If so do nothing
// Else reroute to locally stored URL
But as I don't know how to store the text value of the dropdown I cant do this and maybe there is a more fitting event to hook on to than onload?
Here is a summary of my questions that I need help with in order to fulfill the task at hand:
How do I get the text of the selected dropdown item?
How do I programmaticly select one of the values in the dropdown?
Is there a better event to hook on to than onload?
Anything else that I might have overlooked?
Thanks!
To get the selected text of a drop down list:
JavaScript:
var languageSelect = document.getElementById("LanguageSelect");
var selectedText = languageSelect.options[languageSelect.selectedIndex].text;
jQuery:
$('#LanguageSelect option:selected').text();
Using $("#LanguageSelect").val('ValFromDdl'); will allow you to select an item in a drop down list.
You can use $(document).ready to read your storage object and initialize the drop down list.
I have been trying to figure out how to set the 'selected' attribute on an option within a select box and have fallen short today. Any help would be appreciated.
What I'm trying to accomplish:
When a user chooses an option and hits submit, the data saves to a new mongo document and the new entry is shown on the screen (this part works). Upon browser refresh, the state is lost (due to no selected attribute being set) and the select box goes back to the first option. I need to figure out how to set the selected state depending on the value the user has saved on that particular document. On this page there are many of the same select boxes allowing the user to choose different options for other entries.
References (tried to implement with no luck):
Check for equality in Spacebars?
https://github.com/meteor/meteor/wiki/Using-Blaze#conditional-attributes-with-no-value-eg-checked-selected
How do I indicate 'checked' or 'selected' state for input controls in Meteor (with spacebars templates)?
select box template:
<template name="tEdit">
<div class="form-group">
<div class="controls">
{{> fFEdit}}
</div>
</div>
</template>
select box option template:
<template name="fFEdit">
<select class="form-control" name="fFSelect">
{{#each fFSelect}}
<option value="{{fId}}">{{fF}}</option>
{{/each}}
</select>
</template>
setting data context
Template.fFEdit.helpers({
fFSelect: function() {
var fFArray = [
{ fF: "foo", fId: 0 },
{ fF: "bar", fId: 1 },
{ fF: "buzz", fId: 2 }
];
return fFArray;
}
});
If you want state to be persisted across browser refreshes, you should be able to either fetch it from the server or from something like the Meteor Session.
The second thing you'd need is a helper to get the selected state. Conveniently, Meteor makes the data context available under this (for an each loop, this context is an individual item).
Template.userEdit.helpers({
userSelected: function() {
if(this.id === Session.get("selectedUserId")) {
return "selected";
}
}
});
This assumes you've set the Session variable previously with something like Session.set("selectedUserId", user._id).
Then in your template:
<template name="userEdit">
<select class="form-control" name="userSelect">
{{#each users}}
<option {{userSelected}}>{{username}}</option>
{{/each}}
</select>
</template>
(Note: The selected state can not actually be seen by inspecting the DOM with an element inspector.)
I'm not sure if this is the best answer to my problem, though this is what I came up with to add the selected attribute to the saved option. I welcome anyone else with a better/Meteor solution for this.
When the user clicks the edit link, I find the inputs that need to be updated and assign the values onClick. Ideally I'd rather have this already done on pageLoad, though feel that that solution may impact the initial pageLoad time.
Template.tItem.events({
'click .edit-t-item': function(e) {
e.preventDefault();
var $editTWrapper = $(e.currentTarget).next('.edit-t-wrapper');
$editTWrapper.find('[name=tNEdit]').val(this.tName);
$editTWrapper.find('[name=fFSelect]').val(this.fFId);
}
});
How do I utilize the same variable in both JavaScript code and ASP.NET MVC Razor code?
As you can see from the code below, I created a dropdown and filled it with data.
I want the selected item to be utilized in the below div.
When the user clicks on an item, what is contained within that div is revealed
Then the selected string item is used within the if statement within the div
What currently happens is, the selected item isn't globally accessible, causing the issues you can see below.
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div class="display-field" align="left">
<select name="mydropdown" id="mydropdown" onchange="onChange()">
#foreach (var lLMMI in lIM)
{
<option value="#lLMMI.Key.Product.PCode">
#locItem.Key.Loc.N (#lLMMI.Key.Loc.Code)
</option>
}
</select>
<br /><br />
</div>
}
var itemselected = "";
<div>
<script>
function onChange() {
var item = document.getElementById("mydropdown").value;
$('#summary').show();
}
</script>
<div id="summary">
#foreach (var lLMMI in lIM)
{
if (#lLMMI.Key.Pro.PCode == itemselected.toString())
{
<summary>extra html elements are added etc.</summary>
}
}
You can't use the Javascript variable in the Razor code for two reasons:
They don't exist at the same time
They don't exist in the same place
The Razor code runs on the server to generate the page that is sent to the browser. When the page arrives to the browser it is parsed and the Javascript code runs. To use the Javascript variable in the Razor code would be a time paradox, because it would need to send the value back in time to change how the page was created, but keep the original time line in between...
There are basically two different ways of updating a page depending on input from the user:
Reload the page, including the data in the request.
Use an AJAX call to request that part of the page, including the data as a parameter.
I can't provide you the actual code right now, but here it goes.
You have the following options for your dropdown.
<option value="#lLMMI.Key.Product.PCode">
#locItem.Key.Loc.N (#lLMMI.Key.Loc.Code)
</option>
For example, you want to show #lLMMI.Key.Product.PCode + #lLMMI.Key.Product.PName + #lLMMI.Key.Product.PAddress. Why not load what you will show to your options' values and show them when selected? Like:
<option value="#lLMMI.Key.Product.PCode + #lLMMI.Key.Product.PName + #lLMMI.Key.Product.PAddress">
#locItem.Key.Loc.N (#lLMMI.Key.Loc.Code)
</option>
And change the function to:
function onChange() {
var myDropDown = document.getElementById("mydropdown");
var myValue = myDropDown.options[myDropDown.selectedIndex].value;
var myDiv = document.getElementById("summary");
fieldNameElement.innerHTML = myValue;
}
As others mentioned, you cannot play with Razor (server side) and Javascript (client side) like that. Think of Razor code running only once at the page load. If you want to do stuff after the page load, you need to assign your Razor variables to some client side elements and operate with client side code, JavaScript in your example.
We are working on an application using the CakePHP framework
Basically, its a questionnaire application and it has a few dependant questions, i.e. based on a response to a specific question, it needs to show or hide the next one
For e.g.
Question: Are you married? Yes/No
If the user selects Yes, then using javascript the next question gets displayed for user input
Question: Spouse's name
Saving this information is fine, but when editing, when populating the form, we would want to be able to display the fields for which user has inputted data - in this case, it needs to show the field that has the spouse's name
Since by default we are hiding the spouse name field, when editing, it doesn’t display the field, even though there is a value to it
Is there some way that CakePHP can handle this or does it require us to write some javascript to take care of this?
Thanks in advance.
CakePHP does not manage this for you. While CakePHP is very powerful and a great framework, it will not write this kind of logic for you. You must write it.
I would suggest making the EDIT screen different from the ADD screen. Build the list of values from the database and display the fields that have values (and include any empty fields that should require values).
Keep in mind reusable does not necessarily mean that all CRUD actions fit into the same view.
Like others I advise you use differents EDIT and ADD screens.
But you can try make it with Javascript like this:
<script>
function enableDisableField(targetFieldId){
var targetField = document.getElementById(targetFieldId);
var checkbox = event.target;
console.log(checkbox.checked);
if (checkbox.checked){
targetField.disabled = false;
targetField.value = "empyt";
}else{
targetField.disabled = true;
targetField.value = "empyt";
}
}
</script>
<label><input type="checkbox" onchange="enableDisableField('married')"/> Merried</label>
<?= $this->Form->input('married',['label' => false, 'disabled']); ?>
It works well for ADD, but if you and EDIT you have to change de disable value according a field value:
<label><input type="checkbox" onchange="enableDisableField('married')"/> Merried</label>
<?= $this->Form->input('married',['label' => false, !isset($user->married) ? 'disabled' : '' ]); ?>
Forgive me if this is already 'somewhere' on StackOverflow, but I don't 100% know exactly what it would come under...
I'm trying to retrieve information from a WebService, store this in an array, and then for each <select> within my ASP.Net Datalist, populate it with the array AND have binding attached to an OnChange event.
In other words, I have an array which contains "Yes, No, Maybe"
I've an ASP.Net Datalist with ten items, therefore I'd have 10 <Select>s each one having "Yes, No, Maybe" as a selectable item.
When the user changes one of those <Select>s, an event is fired for me to write back to the database.
I know I can use the [ID=^ but don't know how to:
a) Get the page to populate the <Select> as it's created with the array
b) Assign a Change function per <Select> so I can write back (the writing back I can do easy, it's just binding the event).
Any thoughts on this?
I have built a simple example that demonstrates, I think, what you are attempting to accomplish. I don't have an ASP.Net server for building examples, so I have instead used Yahoo's YQL to simulate the remote datasource you would be getting from your server.
Example page => http://mikegrace.s3.amazonaws.com/forums/stack-overflow/example-multiple-selects-from-datasource.html
Example steps:
query datasource to get array of select questions
build HTML of selects
append HTML to page
attach change event listener to selects
on select value change submit value
Example jQuery:
// get list of questions
$.ajax({
url: url,
dataType: "jsonp",
success: function(data) {
// build string of HTML of selects to append to page
var selectHtml = "";
$(data.query.results.p).each(function(index, element) {
selectHtml += '<select class="auto" name="question'+index+'"><option value="Yes">Yes</option><option value="No">No</option><option value="Maybe">Maybe</option></select> '+element+'<br/>';
});
// append HTML to page
$(document.body).append(selectHtml);
// bind change event to submit data
$("select.auto").change(function() {
var name = $(this).attr("name");
var val = $(this).val();
// replace the following with real submit code
$(document.body).append("<p>Submitting "+name+" with value of "+val+"</p>");
});
}
});
Example datasource => http://mikegrace.s3.amazonaws.com/forums/stack-overflow/example-multiple-selects-from-datasource-datasource.html
Example loaded:
Example select value changed: