I have a cshtml file in which i have following code (a dropdown with data taken from a model)
<div class="controls">
<select ng-model="model.CountryCode" ng-change="countryChanged({{country.ISO316613LetterCode}})">
<option ng-repeat="country in model.Countries" value="{{country.ISO316613LetterCode}}">{{country.CommonName}}</option>
</select>
</div>
And i have this function, in which i detect that a country was chosen from the dropdown
$scope.countryChanged = function(){
var countryDet = _.find($scope.model.CountryDetails, function(cd){
console.log("countryDet");
return cd.CountryCode === $scope.model.Country;
});
if(countryDet){
$scope.model.CountryDetail = countryDet;
// set business properties from country details
$scope.model.DateFormat = countryDet.DefaultDateFormat;
$scope.model.ShortDateFormat = countryDet.DefaultShortDateFormat;
$scope.model.DateFormatJs = countryDet.DefaultJsDateFormat;
$scope.model.LongDateFormat = countryDet.DefaultLongDateFormat;
$scope.model.TaxCode = countryDet.SalesTaxName;
$scope.model.Currency = countryDet.DefaultCurrencySign;
$scope.model.AccSoftwareDateFormat = countryDet.DefaultAccSoftwareDateFormat
$scope.model.WeightSystem = countryDet.DefaultWeightSystem
}
$scope.loadStates();
};
And another function, that should display additional dropdown on web, showing states if the country choosen was USA or AUstralia
$scope.stateVisible = function(){
if($scope.model && $scope.model.CountryDetail){
return $scope.model.CountryDetail.StateVisible;
}
return false;
};
My problem is, that i do not know how to send the selected LetterCode (value of option) to function countryChanged, because, i thought if i do so, then i will be able to easilly load the states into the additional dropdown and show it on site.
Simply use ng-options which will assign the selected model to the ng-model for the <select>. For example
<select ng-model="model.selectedCountry" ng-change="countryChanged()"
ng-options="country.CommonName for country in model.Countries track by country.ISO316613LetterCode">
</select>
Then, your countryChanged() function (and any other controller function) can use $scope.model.selectedCountry which will be a full country object.
Plunker demo ~ http://plnkr.co/edit/tFjvT92B1itmwkRjZIbJ?p=preview
Since you're using $scope for every variable you could use rootScope
https://docs.angularjs.org/api/ng/service/$rootScope
for passing the data.
Related
I can't use Jquery or anything else, just Vanilla Javascript.
My initial approach was to have an array in global scope storing every registered item and then using a foreach to append an <option> child to the <select>, but apparently this only creates one option and renames it
HTML
<label for="productList">Show Products</label>
<select name="products" id="productList">
</select>
JS
let productArray = [];
let dropdown = document.getElementById("productList");
dropdown.addEventListener("click", initializeList());
function initializeList(){
//initializing with an example
productArray.push("PROD1");
productArray.push("PROD2");
productArray.push("PROD3");
productArray.forEach( item => {
option = document.createElement("option");
option.text = item;
dropdown.appendChild(option)
});
}
Unfortunately, this is not a very efficient approach since I'd have to manually create a variable every time I want to add something. I am going to create a method where you just pass an option name and it gets added to the dropdown options. It seems that even though it's a forEach, every option being added is the same. How can I avoid this?
When you setup the addEventListener, you need to send the function itself, not the return value.
You also need to test whether the select list has already been created before running the initializeList function. That way you only initialize it once.
let productArray = [];
let dropdown = document.getElementById("productList");
dropdown.addEventListener("click", initializeList); // send initializeList not initializeList()
function initializeList() {
if (productArray.length != 0) { // Don't initialize more than once
return;
}
//initializing with an example
productArray.push("PROD1");
productArray.push("PROD2");
productArray.push("PROD3");
productArray.forEach(item => {
option = document.createElement("option");
option.text = item;
dropdown.appendChild(option)
});
}
<label for="productList">Show Products</label>
<select name="products" id="productList">
</select>
I'm using the dropdown select menu which redirects users to selected cities. I have searched for this topic everywhere and tried many solutions found on stackoverflow but each of them did not work. In many cases it even disabled the redirection of my dropdown. So I am posting a new question. Hopefully that someone could solve my problem.
Problem: When I visit URL I see select delivery city - non value option. It should show the selected city based on URL address.
My URL looks like this /kategoria-produktu/CITY U SELECT (/kategoria-produktu/cadca/)
To sum up: When u visit url /kategoria-produktu/cadca the dropdown should be preselect on current url and display Čadca.
Any ideas how could I solve this?
Thank you very much!
CODE
JS
if(location.href.indexOf(localStorage.country) == -1){
location.href = localStorage.country
}
function formChanged(form) {
var val = form.options[form.selectedIndex].value;
if (val !== 'non-value') {
if (localStorage) {
localStorage.country = val;
}
if (!location.href.indexOf(val)) {
location = val;
}
}
}
HTML
<form name="form1">
<select id="saleTerm" onchange="formChanged(this); location =
this.options[this.selectedIndex].value;" NAME="country" SIZE="1">
<OPTION VALUE="non-value">Select delivery city</option>
<OPTION VALUE="/kategoria-produktu/cadca/">Čadca</option>
<OPTION VALUE="/kategoria-produktu/brno/">Brno</option>
<OPTION id="bratislava" VALUE="/kategoria-produktu/bratislava/">Bratislava</option>
</select>
</form>
So a bunch of little things need to change here for you to get what you want. I'll try to write them all down:
You should access localStorage using getItem and setItem like in the localStorage MDN documentation
Use an event listener instead of the inline onchange attribute, it's much cleaner.
You probably want to use includes instead of indexOf since you are looking for a substring (country) in a string (href), indexOf won't do this for you.
I used location.pathname since you really only care about the path, there are better ways to get the exact path parameter you want.
No need to use a <form/> as far as I can see from the code you shared.
I removed /kategoria-produktu/ from the option's value attribute since its repetitive and just placed it once in the js
You should change the value of the select to the city you want as the default selected. You can do this by parsing out the city from the path and setting it as the value attribute on the select
I think that's it, here is an example using those points above.
const PREFIX = "kategoria-produktu";
window.addEventListener('load', function() {
let countryInStorage = localStorage.getItem("country");
if (countryInStorage && !location.pathname.includes(countryInStorage)) {
location.href = `/${PREFIX}/${countryInStorage}`;
}
document.getElementById("saleTerm").addEventListener("change", formChanged);
setDefaultOption();
})
function setDefaultOption() {
let countryPath = location.pathname.split("/")[2];
if (countryPath) {
document.getElementById("saleTerm").value = countryPath;
}
}
function formChanged() {
let selectedCountry = this.value;
if (selectedCountry !== "non-value") {
if (localStorage) {
localStorage.setItem("country", selectedCountry);
}
if (!location.pathname.includes(selectedCountry)) {
location.href = `/${PREFIX}/${selectedCountry}`;
}
}
}
<select id="saleTerm" name="country">
<option value="non-value">Select delivery city</option>
<option value="cadca">Čadca</option>
<option value="brno">Brno</option>
<option value="bratislava">Bratislava</option>
</select>
If I understand it correctly, you are looking onto showing the proper option from the select element based on the URL.
Look at the example below. It basically runs a process on page load and when the DOM is ready (hence DOMContentLoaded) to check if an option based on URL exists in the select options and picks that. You may have to update your logic depending on the URL structure. The example below assumes your URL is always formatted like http://your.domain.com/kategoria-produktu/<city>/.
document.addEventListener("DOMContentLoaded", function() {
// find the option based on the URL.
let option = document.querySelector("#saleTerm > option[value='" + location.pathname + "']");
// assign the option value to the select element if such exists.
if (option) {
document.querySelector("#saleTerm").value = option.value;
}
});
This question my seems silly to you but i just want to know that is it possible to show ionic loader in between the process of rendering data in dropdown by ng-repeat.I goggled and found two directives one is for after-render and other is for on-finish-render both works good but i am really confused that how can i show and hide my ionic loader during this whole process.
here is some of my code :-
<label class="item item-input"> <select class="input-select"
ng-model="user.country.value"
ng-change="selectedCountry(user.country.value)">
<option ng-selected="country.value==user.country.value"
ng-repeat="country in results" value="{{country.value}}">
{{country.name}}</option>
<option value="" disabled hidden>{{'checkoutPage.country' |
translate}}</option>
</select>
</label>
<label class="item item-input" ng-if="showDropDownInStateLabel()">
<select class="input-select" ng-model="userState.states.region_id"
ng-change="selectedState(userState.states.region_id)">
<option ng-selected="states.region_id==userState.states.region_id" ng-repeat="states in StatesArray" on-finish-render="ngRepeatFinished"
value="{{states}}">{{states.name}}</option>
<option value="" disabled hidden>{{'checkoutPage.state' |
translate}}</option>
</select>
</label>
here is directive :-
app.directive('onFinishRender', function($timeout) {
return {
restrict : 'A',
link : function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
scope.$emit('ngRepeatFinished');
});
}
}
}
});
here is the listener for event:-
$scope.$on('ngRepeatFinished', function(
ngRepeatFinishedEvent) {
alert("rendering ends here");
});
can any one tell me that how to show loader to user when ng-repeat rendering the data in dropdown.I even try by making two different functions for showloader() and hideloader() . showLoader i call when user select some value in dropdown and hideLoader gets call in $scope.$on function.
Actually i am having two dropdowns one is for countries and other is for their respective states.When user select country that state dropdown got visible to user.this whole process took some time in rendering which make application looks like hanged to user so i just want to display user a loader to avoid this illusion.
here is the function which finds which country have states array and according to which stats dropdown got visible to user :-
$scope.user = {};
$scope.selectedCountry = function(value) {
// alert(value);
$scope.data.region = '';
if (angular.isString(LocalStorage
.getData("StateSelected"))) {
LocalStorage.setData("StateSelected", "");
LocalStorage.setData("Statename", "");
}
if (angular.isString(LocalStorage
.getData("Addressregion"))) {
LocalStorage.setData("Addressregion", "");
}
$scope.user.country_id = value;
LocalStorage.setData("CountrySelected", value);
for ( var c = 0; c < LocalStorage
.getObject("getCountriesresult").length; c++) {
if (value == LocalStorage
.getObject("getCountriesresult")[c].value) {
if (LocalStorage
.getObject("getCountriesresult")[c].state.length > 0) {
shouldShowDropdown = true;
$scope.StatesArray = LocalStorage
.getObject("getCountriesresult")[c].state;
} else {
shouldShowDropdown = false;
}
}
}
}
Any help will be appreciated,
Thanks
This kind of feature should never take so long to execute.
I think you should try to remove the huge amount of LocalStorage access inside loops. From what I saw, you can do everything you want using local variables (in-memory).
$ionicLoading works fine for async calls that take time, like an AJAX call.
I have three select menu that bind to each other and want to set selected value of two select menus. Value that I want to set comes with scope. I try ng-init but that didn't work. Working Plunker
<select ng-init="selManga=direk" ng-model="selManga" ng-options="manga.seri for manga in mangas">
<option value="">Select a Manga</option>
</select>
<select ng-init="selChapter=bacanak" ng-show="selManga" class="browser-default" ng-model="selChapter" ng-options="+idx as chapter.klasor for (idx, chapter) in selManga.randomword">
<option value="">Chapter</option>
</select>
<select ng-show="selManga.randomword[selChapter].yol" class="browser-default" ng-model="selPage" ng-options="+idx as (+idx + 1) for (idx, page) in selManga.randomword[selChapter].yol">
<option value="">Page</option>
</select>
Javascript:
.controller('nbgCtrl',function ($scope, MMG, $stateParams) {
$scope.direk = $stateParams.seri;
$scope.bacanak = $stateParams.klasor;
MMG.adlar.success(function(loHemen) {
$scope.mangas = loHemen;
});
$scope.next = function (manga, chapter, page) {
var nextPage = page + 1;
if (angular.isDefined(manga.randomword[chapter].yol[nextPage])) {
$scope.selPage = nextPage;
} else if (angular.isDefined(manga.randomword[chapter + 1])) {
$scope.selChapter = chapter + 1;
$scope.selPage = 0;
}
}
})
To extract the values for the manga,chapter and page from the url you should use the $routeParams object, which your module should include ngRoute.
I've prepared an example here it might not be obvious but if you download the code and run it in your own browser you can access routes like Manga/Naruto/ch/100 from the url bar.
Once you've restructured your application to use routes and routeParams, in my example I directly bind the chapter and page I get from the url to the view but if you bind them to the models of your dropdowns the dropdowns will update.
$scope.params = $routeParams;
$scope.selManga = $scope.params.bookId
This does not update the url as you select from the dropdown.
In your code you have assign direk and bacanak value more than one times which can cause issue. Set variable property only once.
$scope.direk = $stateParams.seri;
$scope.bacanak = $stateParams.klasor;
$scope.direk = $stateParams.xy; //Remove if not required
$scope.bacanak = $stateParams.xz; //Remove if not required
Set selManga value from $stateParams instead of setting it to direk
$scope.selManga = $stateParams.seri; // Set selManga from $stateParams
$scope.selChapter = $stateParams.klasor; // Set selChapter from $stateParams
The reason why ng-init="selManga=direk" not work is because Syntax error: ng-init="selManga=direk" should be ng-init="selManga='direk'" but after making syntax correct, dropdown will not set because of ng-repeat. ng-init set value to model but at time of setting value ng-repeat doesn't complete setting value for options so selManga set from ng-init not update option to dropdown.
I want to ask quick question, i want to make a select drop down that when i choose one of the options the values of the other select drop down change ...
let's say i have select drop down called model that has the following
- Acura
- Aston martin
- Audi
I want when i choose (let's say ) Audi, in the type select drop down i find Audi type's only
- A3
- A5
- A4
I don't want to use AJAX calls, i just want to use javascript or jquery to filter the data
thanks guys
Like Shomz said,
Assuming the dropdowns look like this:
<!-- First dropdown. Make of car -->
<select name='Manufactor' id='make'>
<option value='null'>Select a Make</option>
<option value='Audi'>Audi</option>
<option value='BMW'>BMW</option>
<option value='Volvo'>Volvo</option>
</select>
<br />
<!-- Second dropdown. Model of car -->
<select name='Model' id='model'>
</select>
The javascript would look like this:
<script type='text/javascript'>
var model = ['','audi','bmw','volvo']; //Set makes
model[1] = ['A3', 'A5', 'A4']; // Set Audi models
model[2] = ['M3', 'M5', 'M6']; // Set BMW models
model[3] = ['C30', 'C70']; // Set Volvo models
var test = model[1][1];
function setModel(index) {
var modelDropdown = document.getElementById('model');
modelDropdown.options.length = null;
for(var i = 0; i < model[index].length; i++) {
modelDropdown.options[i] = new Option(model[index][i]);
}
}
window.onload = function() {
var makeDropdown = document.getElementById('make');
makeDropdown.onchange = function() {
setModel(this.selectedIndex);
}
}
</script>
Notice that the Models start at index 1 and not 0, because the first option is a blank Select Model option.
AJAX calls would still be the best solution, but if you don't want to use them, you can always manually create arrays for each of the main options, make an onchange event on the select element which would call the selected array and create another dropdown based on the elements of that array. Hope I didn't make it sound to complicated, since it isn't.
Here's a sample how to extract values with jQuery.