Loading specific div based on the results of multiple dropdowns - javascript

EDIT: Would the approach be much easier if the Javascript listed was removed completely, and the dropdown menus restyled as <div>'s within <li>'s, and the final div was generated by a Javascript onclick event? e.g.
<a id="click_link">click me</a>
$("#click_link").click(function(){
$('#div').load('http://www.link.com/');
});
Either way, the problem at hand...
My decision to use an elegant-looking javascript solution is highlighting my massive inexperience when it comes to javascript! The problem is, on the face of it, simple...
Once an option has been chosen on each of the dropdown menus, I need a final div to load so that a specific button can be shown (a link to buy the item with the specified options, e.g. choosing Necklace D, with Stone Option B, and Delivery Option A = loading div with 'Buy' Button #17)
The dropdowns are divs that are filled and styled through the Javascript (as opposed to using the simpler <form> and <input> method), giving the flexibility to add two lines of differently styled text for each option etc. - This is where I step into the realm of the unknown and my inexperience shines through.
The isolated section is viewable in its entirity here
Ok, to the code.
Here's the Javascript:
function createByJson() {
var pearlData = [
{description:'Choose your pearl...', value:'Pearls', text:'Pearls'},
{description:'Beautiful black stone', value:'Black Pearl', text:'Black Pearl'},
{description:'Classic white stone', value:'White Pearl', text:'White Pearl'}
];
$("#DropItPearls").msDropDown({byJson:{data:pearlData, name:'pearls', width: 200}}).data("dd");
var blodeuweddData = [
{description:'Choose your item...', value:'Blodeuwedd', text:'the Blodeuwedd Collection'},
{description:'A striking statement', value:'BlodeuweddCelticStatement', text:'Celtic Statement Piece'},
{description:'Gold laced flower and pearl', value:'BlodeuweddBracelet', text:'Bracelet'},
];
$("#DropItBlodeuwedd").msDropDown({byJson:{data:blodeuweddData, name:'blodeuwedd', width: 250}})
.msDropDown({on:{change:function(data, ui) {
var val = data.value;
if(val!="")
window.location = val;
}}}).data("dd");
var deliveryData = [
{description:'Choose your method...', value:'Delivery', text:'Delivery Options'},
{description:'4-6 weeks delivery', value:'Four Weeks', text:'Made To Order'},
{description:'(unavailable on this item)', value:'Rush', text:'Express Delivery', disabled:true}
];
$("#DropItDelivery").msDropDown({byJson:{data:deliveryData, name:'delivery', width: 200, selectedIndex: 1}}).data("dd");
paymentData = [
{ description:'How would you like to pay?', value:'Payment', text:'Payment Method'},
{image:'images/msdropdown/icons/Visa-56.png', description:'Secure online payment', value:'Visa', text:'Visa'},
{image:'images/msdropdown/icons/Paypal-56.png', description:'Secure online payment', value:'Paypal', text:'Paypal'},
{image:'images/msdropdown/icons/EmailPay-56.png', description:'Order by email', value:'Email Payment', text:'Send Your Details'},
{image:'images/msdropdown/icons/Mastercard-56.png', description:'(coming soon)', value:'Mastercard', text:'Mastercard', disabled:true},
{image:'images/msdropdown/icons/Collect-56.png', description:'(coming soon)', value:'Collection', text:'Order and Collect', disabled:true},
{image:'images/msdropdown/icons/Email-56.png', description:'email Menna', value:'Other Method', text:'Alternatives'}
];
$("#DropItPayments").msDropDown({byJson:{data:paymentData, name:'payments', width: 250}}).data("dd");
}
$(document).ready(function(e) {
//no use
try {
var pages = $("#pages").msDropdown({on:{change:function(data, ui) {
var val = data.value;
if(val!="")
window.location = val;
}}}).data("dd");
var pagename = document.location.pathname.toString();
pagename = pagename.split("/");
pages.setIndexByValue(pagename[pagename.length-1]);
$("#ver").html(msBeautify.version.msDropdown);
} catch(e) {
//console.log(e);
}
$("#ver").html(msBeautify.version.msDropdown);
//convert
$("select").msDropdown();
createByJson();
$("#tech").data("dd");
});
function showValue(h) {
console.log(h.name, h.value);
}
$("#tech").change(function() {
console.log("by jquery: ", this.value);
})
//
And the html:
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Item</p></div>
<div id="DropItBlodeuwedd"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Precious Stones</p></div>
<div id="DropItPearls"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Payment</p></div>
<div id="DropItPayments"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Delivery</p></div>
<div id="DropItDelivery"></div>
</div>
<div id="dropOptions">
<div id="dropOptionsTitle"><p>Buy Now!</p></div>
<div id="DropItBuy"></div>
</div>
Again, working version viewable here
Many thanks in advance!

What I think you want is for your Buy button to dynamically read what the dropdowns currently say and build a link for redirection based on that, rather than trying to update the Buy button every time a dropdown changes.
From your code I can't see what the form of the final URL is supposed to be. For example, to get the current value of the delivery option, you can check $('#DropItDelivery :selected').text() which will be something like "Made To Order".
Your Buy Now! could be a button with a click event that reads these values and constructs the URL with basic string concatenation, e.g.:
window.location = "buynow.html?delivery=" + $('#DropItDelivery :selected').text() +
"&payment=" + $('#DropItPayments :selected').text()
// etc.
Of course you'd have to handle these options on the server.
In case you want to redirect to the payment page of the processor, you can just branch based on the payment method and give them the URL you want based on that.
var pm = $('#DropItPayments :selected').text();
if (pm == "Visa")
{
// Visa payment URL construction
}
else if (pm == "Send Your Details")
{
// Send your details URL construction
}
// etc.

Related

How to store values from ng-dropdown-multiselect in sessionStorage in AngularJS?

I am looking for a simple way to save and load data to / from session storage when it comes to multiselect dropdown. I'm using AngularJS.
Saving and loading data happens on a page reload.
HTML:
<div class="select-wrapper">
<p class="par-multiselect-title">Items to choose from: </p>
<div ng-dropdown-multiselect="" options="items" selected-model="selectedItems" extra-settings="mySettings"></div>
</div>
Here is how I solved it when it comes to single text input or checkbox. I can't however crack multiselect dropdown.
sessionStorage.setItem("name", $('#name').val());
sessionStorage.setItem("isNew", document.getElementById("isNew").checked);
if (sessionStorage.getItem("name")) {
$scope.itemName = sessionStorage.getItem("name");
}
var isNewChecked = JSON.parse(sessionStorage.getItem("isNew"));
if (isNewChecked == true) {
document.getElementById("isNew").checked = isNewChecked;
}
If sessionStorage.setItem supports string only, you can stringify the json:
$scope.selectedItems = [/* ... */];
sessionStorage.setItem("selectedItems", JSON.stringify($scope.selectedItems));
and load:
$scope.selectedItems = JSON.parse(sessionStorage.getItem("selectedItems"));

how to refresh/reload/update accordion datas with new datas?

could some one tell me, how to update accordion datas with new values on button click as when user enter their input?
assume like there is input box. user hit submit after giving value. at the same time it should show the input what user gives in side accordion.
accordion ll be categorized as
/Latest update
/old updates
/etc
what am having is
$("className").click(function(){
setInterval(function(){
}, 900);
})
<div classname="className"></div>
it would be better if share fiddle/plunker snippets for Typescript, Jquery or even Angular2
many thanks for any help
because i had some free time i made you an example of what i think you want.
1.enter 'aa' the latest updates will slideDown and have text 'aa'
2.enter second value 'bb' the latest updates will have text 'bb' , old updates will have text 'aa' and also 'aa' is archived
3.enter third value 'cc' the latest updates will have text 'cc', old updates will have text 'bb' and archive will have 'aa' and 'bb'
and so on.
this is made using IF conditions which are very straight forward using text().length.
also included ( at the beginning of the JQ ) a simple accordion code
let me know if this is what you were looking for. check snippet below or jsFiddle
var accTrigger = $('h2')
$(".text").hide()
$("h2").on("click", function() {
var text = $(this).siblings(".text")
if ($(text).is(":visible")) {
$(text).slideUp()
} else {
$(text).slideDown()
}
$(this).parents(".accordion-item").siblings().find(".text").slideUp()
});
var button = $("button"),
input = $("input"),
latest = $("#latest .text"),
old = $("#old .text"),
archive = $("#archive .text")
$(button).on("click", function() {
inputValue = $(input).val()
if ($(latest).text().length > 0) {
$(old).text($(latest).text()).slideDown()
}
if ($(old).text().length > 0) {
var aText = $(archive).html()
$(archive).html(aText + '<br>' + $(old).text()).slideDown()
}
$(latest).text(inputValue).slideDown()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="accordion">
<div class="accordion-item" id="latest">
<h2>Latest Updates</h2>
<div class="text"></div>
</div>
<div class="accordion-item" id="old">
<h2>Old Updates</h2>
<div class="text"></div>
</div>
<div class="accordion-item" id="archive">
<h2>Archive</h2>
<div class="text"></div>
</div>
</div>
<input type="text" value="">
<button type="submit">
submit value
</button>

How to display the selected items in the new page?

Whenever I click on view the items are selected on same page. I need to display them on the new page, but I am not able to do that.
<html ng-app="countryApp">
<body ng-controller="CountryCtrl">
<div ng-repeat="x in models track by $index">
<button ng-click="select(x, $index)">View Me</button>
</div>
Selected Model:
<p> {{selected.name}} </p>
<p> {{selected.brand}} </p>
<p> {{selected.price}} </p>
<p> {{selected.quan}} </p>
<p> {{selected.sku}} </p>
</body>
Function:
<script>
var countryApp = angular.module('countryApp', []);
countryApp.controller('CountryCtrl', function ($scope){
$scope.select = function(brand) {
$scope.selected = brand;
}
$scope.models = [
{ brand: "Brand: Apple", id: 980190962, name: "Name: iPhone 5", price: "Price: $199", quan: "Quantity: 1", sku: "SKU:1234" },
{ brand: "Brand: Samsung", id: 298486374, name: "Name: Galaxy S3", price: "Price: $199", quan: "Quantity: 2", sku: "SKU:5678"}
]
});
</script>
</html>
You can use two options either store that selected user to localstorage or somewhere and read that in details view like
localStorage.setItem('myObj',JSON.stringify(brand));
and retrieve that in details view like
JSON.parse(localStorage.getItem('myObj'));
OR
I will prefare to use parent child relationship in this suppose you have a parent controller named 'CountryCtrl' and two child controllers 'CountryListCtrl' and 'CountryDetailCtrl'. List page is bind to 'CountryListCtrl' and details view is bind to 'CountryDetailCtrl' and on top you have 'CountryCtrl'. You can change your view using ng-include etc. When moving from List to Detail Controller set an object on parent controller and it will be accessible to both Controllers. You can learn about parent and child relationship in angularjs on internet there are tons of article available.
Thanks.
To show the details of the selected item in a new tab, there are multiple ways to achieve this. One way is to add a form with attribute target="_blank" (to open the action attribute in a new tab) and submit it in the select() function.
So you can add a form, like this:
<form id="openNewTabForm" target="_blank" method="GET"></form>
Then update the function to submit the form. There are multiple ways to pass the data about the selected phone - e.g. store the data in form fields, serialize the data and store it in a cookie, in localStorage, etc. Here is an example using hidden form fields:
$scope.select = function(phone) {
var form = document.getElementById('openNewTabForm');
form.action = action="selectedPhone.html";
Object.keys(phone).forEach(function(field,index) {
var input = form.elements[field]; //look for an existing form field for this field
if (input) { //update existing form field
input.value = phone[field];
}
else { //create a new form field for this
input = document.createElement('input');
input.type = 'hidden';
input.name = field;
input.value = phone[field];
form.appendChild(input);
}
});
form.submit();
$scope.selected = phone;
}
Then have a new page (e.g. selectedPhone.html) that takes the values submitted with the form. This could be a server-side page (e.g. with PHP, Ruby, etc), in which case you would set the attribute method="POST" on the form. Or you can just use a regular HTML page and process the query string. You could also use AngularJS + UI Router, VueJS, etc. to modify the URL after it has been loaded.
Take a look at this Plunker example I made for an example. I would have included a code snippet that would run here but SO doesn't (currently) allow having a form submission open a new tab because it is sand-boxed.
Another approach might be to use window.open() for opening a new browser window but that might lead to issues with popup blockers for some users.
You can open new modal on click of button function like following -
In controller:
$scope.showDetails = function(){
// open new html modal to show new screen using following
$ionicModal.fromTemplateUrl('templates/views/details.html',{
scope: $scope,
animation: 'none',
backdropClickToClose: false
}).then(function(modal){
$scope.modal= modal;
$scope.modal.show();
});
}
In HTML:
<div ng-repeat="x in models track by $index">
<button ng-click="showDetails (x, $index)">View Me</button>
</div>
By using new modal (screen) you can design as you required as well.

Update documents based on multiple dropdown values

I am building an administration panel within a meteor app to be able to manage the users of the app. Currently I am displaying all the users with a dropdown for each user to change their role .
I need to update the changed roles only after I hit some confirmation button at the end.
I have a template that gets rendered with the username and a dropdown with the current role of the user, my template is similar to this:
<div class="ui selection dropdown">
<input type="hidden" name="role">
<i class="dropdown icon"></i>
<div class="default text">{{role}}</div>
<div class="menu">
<div class="item" data-value="admin">Admin</div>
.
.
.
<div class="item" data-value="user">User</div>
</div>
</div>
This renders as many as users I have in my database. I need to update all users who have their role changed after clicking a button.
My current approach is to plug the user id to the dropdown:
<div class="ui selection dropdown" id={{_id}}>
Then I have an event handler for the dropdown change and catch the value:
Template.templateName.events({
"change .ui.selection.dropdown": function(event, template) {
var id = template.find(".ui.selection.dropdown").id;
var role = template.find("input[name=role]").value;
...
},
});
Now I am wondering if I should push those id,role pairs in some session key and update the users after clicking save button or there is a better and more effective alternatives for this ?
Instead of saving them in session variable and clearing session variable on template's destroyed callback, you can add an attribute to the changed element indicating that the element has changed. When save button is clicked, you can use attribute selector to get all the elements that were changed by this user. See the code sample below for further reference.
Template.templateName.events({
"change .ui.selection.dropdown": function(event, template) {
var target = $(event.target);
target.attr("data-changed", "data-changed");
},
"click #saveButtonId": function(event, template) {
var changedElements = template.$(".ui.selection.dropdown[data-changed]");
var changedItems = [];
for (var i = 0; i < changedElements.length; i++) {
var changedElement = changedElements[i];
changedItems.push({ id: changedElement.id, value: changedElement.value });
// or
//changedItems.push([changedElement.id, changedElement.value]);
}
// here you can call a meteor method like
// Meteor.call('updateUserRoles', changedItems); //this updateUserRoles will now get only changed items that you can update in your DB.
}
});

Partial view with ajax and jQuery UI.Dialog

I am using a standard MVC4 EF5 setup and have a standard view which loads data from the db onto a table.
At the start of the table I have a column for each record with an Add button. The functionality I want is to click the button, popup a model dialog box with a form and add something to the item in the grid that was clicked (a 1 to many).
Lets say I have a list of vans available shown in the list. And when I click the add button beside the particular van where I want to add a passenger, I want a popup to show that allows me to type the details of the passenger so they can be assigned to that van.
I think I am over complicating this. But my brain is fried. I tried partial views with ajax. I tried jQuery UI.Dialog. Im just lost. I am trying to figure out how to find the id of the record I clicked (given the buttons are all generated by a for each loop in the view as normal and numbering them 1 to X does not tell me the id of the record I clicked). So even if I get the popup showing, I wont know which van to assign the passenger to.
If your woundering where the passenger list is coming from, its another table. And effectively any passenger can be assigned to any van. Its hypothetical.
Im actually working on a document generator and so there is a many to many relationship between document parts and documents (a given document part, can appear or belong to many documents, and a document can contain many document parts). I know its messy, this is why I did not want to use the real example.
I'm thinking its maybe an easy enough problem to solve but I have been at it since Friday and the brain left home!
Edit: Adding Code:
Here is the main view: The main problem I am having with this is the way the grid is constructed. I think its partially razor, partially html, partially html helper, and partially javascript. I don't know which part is which, but I just need to get a popup to show for each button in the table, and to have an id I can assign values to. I cant figure out how to do it here.
Html.Grid(dbaccess().Where(c => something = something
).Select(o => new
{
Name = o.Name,
Comment = o.Comment,
Status = o.Status,
}
, "grdConfiguration", 0, htmlRowClass: (p) => (row++ % 2 != 0) ? "" : "oddRow"
, columns: new[]{
//THIS IS THE PROBLEM LINE BELOW .... It shows a button in the table, but...
//how do I make it unique. Is it even necessary to do so.
// How do I get the ID of the record at this location when this button is pressed.
//This is the code as originally posted: For context
new Helpers.GridColumn(value: (a) => "<input type=\"button\" class=\"btn\" id=\"BtnHello\" value=\"Add\" />"),
//for some reason when I try the following alternative as suggest by the answers so far - it doesn't work.
new Helpers.GridColumn(value: (a) => "<input type=\"button\" class=\"btn\" data-ThisId=\"#model.SomeId\" value=\"Add\" />"),
//THIS IS THE PROBLEM LINE ABOVE....
there is more columns but this button calls the jQuery...
On this view I also have some Div tags in which to load the partial... I can actually get this to popup. But that's about all I can do. And only when I click the first button in the table.
<div id='SomePopUp' style='display: none;'>
//#using (Html.BeginForm())
//{
// <div>
// <span class="display-label">Quantity: </span>
// <span class="display-field"><input type="text" id="txtQuantity" /></span>
// </div>
// <div>
// <span class="display-label">Comments: </span>
// <span class="display-field"><textarea rows="7"></textarea></span>
// </div>
//}
</div>
I also have a script section on this view with the code for the popup:
<script type="text/javascript">
$("#BtnHello").click(function ()
{
$("#SomePopUp").dialog(
{
resizable: false,
height: 400,
width: 400,
modal: true,
title:"add to {Some ID}:", //I want the id to show here so I know I have the record I want.
buttons:
{
Submit : function ()
{
$(this).dialog('Some Text');
},
Cancel: function ()
{
$(this).dialog('close');
}
}
});
});
</script>
I have a controller:
[HttpGet]
public ActionResult AddExtra(int id)
{
//Fairly sure I should be doing something with this id, but how do I get it from the button.
return PartialView();
}
And for the partial view I have
#model CM.ViewModels.AddExtraPackagesViewModel
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Add Something</h3>
</div>
<div>
//I was using ajax here...
#*#using (Ajax.BeginForm("DoSomething", "Something", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "list-of-something"
}))
{
<div class="modal-body">
#Html.TextBoxFor(x => x.Quantity);
#Html.TextAreaFor(x => x.Comment);
</div>
<div class="modal-footer">
<button class="btn btn-success" id="submit">Save</button>
Close
</div>
}
</div>
I made a little view model too but...
public class AddExtraViewModel
{
public int Id { get; set; }
public string Quantity { get; set; }
public string Comment { get; set; }
}
I apologise if this is all over the place but I did not write the original code. There were about 7 other programmers here before me and I'm just struggling to get through it.
Any help would be appreciated.
I think you would want something like this (using jQuery and jQuery UI):
Controller:
public ActionResult SomeAction(int id) {
return View(new YourModel { Id = id });
}
Partial View:
#model YourProject.Models.YourModel
// Partial view content e.g. the form etc.
Your view:
/<!-- html etc. -->
<table>
<tr>
<td>Add</td>
</tr>
</table>
<script>
$(function(){
$(".add-button").click(function(){
var options = {
autoOpen: false
}
var dialog = $("<div>").dialog(options);
var id = $(this).data("theId");
dialog.load("the/url/to/the/controller/action", { id: id }, function(){
dialog.dialog("open");
dialog.find("form").submit(function(){
// do stuff
dialog.remove();
return false;
});
});
});
});
</script>
if you are building buttons in a forloop you don't want to define an id on the button. Duplicate id's on a view can cause lots of issues. Use a class on the buttons instead to trigger off of and use $(this) in your script to get details of the button that was clicked. To access buttons on a partial or on items that are added to your page after page load you need to tie the click event for that button to the document like this
$(document).on("click", ".btnDetails", function(){
//your script here
});
The other example uses "this" and shows how you can pass the id of the clicked button back to the controller. The controller will need to be a little different though
public PartialViewResult PopulatePartial(int ID){
var Model = //populate your model based on the passed id
return PartialView("PartialViewName", Model);
}

Categories

Resources