I am using nodejs and expressjs.
I load a list from a database. Selecting any of the list elements bring up an overlay with to EDIT and DELETE the selected item. I can not figure out how to send the selected list item to the express route.
What I believe needs to be done: Dynamically assign an ID to the buttons on the overlay. I tried to make a jfiddle but the overlay would not work.
Any ideas? I am sliding the overlay into view with jquery.
Thank you for taking the time to read this
I have a dynamically created list, each item with the class ".recordlongpress" and I apply this Jquery functionality to it.
$(document).ready(function(){
$('.recordlongpress').bind('tap', function() {
return;
});
$('.recordlongpress').bind('taphold', function() {
$('#overlay').fadeIn('fast',function(){
$('#box').animate({'top':'100px'},500);
});
});
$('#boxclose').click(function(){
$('#box').animate({'top':'-100px'},500,function(){
$('#overlay').fadeOut('fast');
});
});
});
Which brings up my overlay which is done by a combination of CSS and this HTML
<div class="overlay" id="overlay" style="display:none;"></div>
<div class="box" id="box">
<a class="boxclose" id="boxclose"></a>
<button onclick="location.href='/scape/editcustomerform/id'">Edit Contact</button>
<button onclick="location.href='/scape/deletecustomer/ID'">Delete Contact</button>
<button>E-mail Customer</button>
<button>Call Customer</button>
<button>GPS to Address</button>
<button>Create Quote</button>
<button>Create Sales Order</button>
<button>Create Cash Sale</button>
</div>
</div>
I have tried to append the path id to the end of my route, but it just literally takes the word id. Thank you for any help
Try this:
var box = document.getElementById('box'),
buttons = box.getElementsByTagName('button');
for(var i = 0; i < buttons.length; i++){
buttons[i].id = [ 'my', 'button', 'id', i ].join('-');
}
JsFiddle
Also, you may try to "map" actions:
var box = document.getElementById('box'),
buttons = box.getElementsByTagName('button');
var map = [
'editcustomerform',
'deletecustomer',
'emailcustomer',
'callcustomer',
'gpstocustomer',
'createquote',
'createsalesorder',
'createcashsale'
];
for(var i = 0; i < buttons.length; i++){
buttons[i].id = [ 'my', 'button', 'id', i ].join('-');
buttons[i].onclick = function(){ location.href = [ '/scape', map[i], 'id' ].join('/'); }
}
Related
i'm using fabric js and trying to remove group of items when try to remove the parent item of group. following is my code.
jQuery(document).on('click', ".deleteBtn", function () {
if (canvas.getActiveObject()) {
var product_id = canvas.getActiveObject().get('product_id');
}
var canvasObj = canvas.getObjects();
for(var i = 0; i < canvasObj.length; i++){
var objRef = canvasObj[i];
var accessoryId = objRef.get('accessory_product_id');
var product_type = objRef.get('product_type');
if(accessoryId == product_id && product_type == "accessory"){
canvas.remove(objRef);
}
}
});
code is actually working, but not removing all items with same accessoryId and product_type parent item which is the active object trying to remove and two other items are removing properly. only two items left on canvas. there are all 5 items in group. those are images. i'm unable to find the issue please help. thanks!
HTML code
<div id="content-tab-3" class="visualiser-product-category content-tab active">
<ul>
<li>
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter_Spice.png" class="visualizer-product-img" alt="Placeholder" data-quantity="1" data-product_type="parent" data-product_id="343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Desk-Floral.jpg" class="hide accessory-343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Garland.jpg" class="hide accessory-343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Tabletop.jpg" class="hide accessory-343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Wreath.jpg" class="hide accessory-343">
</li>
</ul>
</div>
Hello i noticed on your code that you try to get the active's object id, but no matter if there is active object or not you proceed to the loop, to delete the objects!!
Maybe, that causes the problem.
I'm going to show an example with forEach() function, but proceed to delete objects ONLY if there is active object:
jQuery(document).on('click', ".deleteBtn", function () {
//only if there is active object, do i delete objects
if (canvas.getActiveObject()) {
//get productId of active object
var product_id = canvas.getActiveObject().product_id;
//loop on the canvas objects
canvas.getObjects().forEach(function (object) {
if(object.accessoryId == product_id && object.product_type == "accessory"){
canvas.remove(object);
}
});//end forEach
}//end if
});//end 'click'
Hope helps, good luck.
I have a have several divs on a page called parent_container inside it I have a heading, image and a button
how can I get the value for the specific heading of the container it was clicked from?
<div class="parent_container">
<img class="news_image" src="/" />
<h1 class="product_title">title 1</h1>
<a class="cta-btn" href="#">button1</a>
</div>
<div class="parent_container">
<img class="news_image" src="/" />
<h1 class="news_title">title 2</h1>
<a class="cta-btn" href="#">button2</a>
</div>
//getting the elements
var update_buttons = document.getElementsByClassName( 'cta-btn' ),
parentElement = document.getElementsByClassName( 'parent_container' ),
itemTitle = document.getElementsByClassName( 'news_title' );
//trying to get the title from the div it was clicked in
var getTitle = function( evt ) {
var title = this.itemTitle;
console.log( title ); //undefined
}
//setting up a event listener on all the buttons on the page
for( var i=0;i<update_buttons.length;i++ ){
update_buttons[i].addEventListener('click', getTitle);
}
Get the clicked element using evt.toElement (In this case, this works too, though).
From there, get the parent node, and then select the child h1 element.
Access the text using textContent:
var getTitle = function (evt) {
var el = evt.toElement, // or this
parent = el.parentNode,
header = parent.querySelector('h1[class*="title"]'),
headerText = header.textContent;
console.log(headerText);
}
Example Here
..and if you prefer not to cache variables:
evt.toElement.parentNode.querySelector('h1[class*="title"]').textContent;
//getting the elements
var update_buttons = document.getElementsByClassName('cta-btn'),
parentElement = document.getElementsByClassName('parent_container'),
itemTitle = document.getElementsByClassName('news_title');
//trying to get the title from the div it was clicked in
var getTitle = function (evt) {
var el = evt.toElement,
parent = el.parentNode,
header = parent.querySelector('h1[class*="title"]'),
headerText = header.textContent;
console.log(headerText);
}
//setting up a event listener on all the buttons on the page
for (var i = 0; i < update_buttons.length; i++) {
update_buttons[i].addEventListener('click', getTitle);
}
<div class="parent_container">
<img class="news_image" src="/" />
<h1 class="product_title">title 1</h1>
<a class="cta-btn" href="#">button1</a>
</div>
<div class="parent_container">
<img class="news_image" src="/" />
<h1 class="news_title">title 2</h1>
<a class="cta-btn" href="#">button2</a>
</div>
Solution with the least steps. It seams that your title is always the previous element of the button.
Use:
var getTitle = function( evt ) {
var title = this.previousElementSibling.textContent || this.previousElementSibling.innerText;
console.log( title ); //undefined
}
To be sure that you always return the correct element you need a bit more than the sample above. Why am I saying this. If you (or someone else) edits the html the solution above could break. A better solution is to give the title element a class name or better an attribute that is only used for those titles. Take a look at this solution:
<div class="parent_container">
<img class="news_image" src="/" />
<h1 title-element class="news_title">title 2</h1>
<a class="cta-btn" href="#">button2</a>
</div>
var getTitle = function( evt ) {
var title = this.parentElement.querySelector("h1[title-element]");
return title.textContent || title.innerText;
}
The above answer makes it less likely that your function breaks when the html gets updated in the future.
PS. The || element.innerText is a fall back for older browsers (read IE) that don't support textContent.
First you got a typo: console.log(title). And here is what you need to do, get the parent, then the child for the header:
var title = this.parentNode.children[1].innerHTML;
console.log( title );
Example Here
Note this assumes that you have the same structure for the <div class="parent_container"> item, such that the title is the second item.
Edit
If the structure is changed you can select the item with querySelector('h1'):
var title = this.parentNode.querySelector('h1').innerHTML;
console.log( title );
As #JoshCrozier proposed you can use .querySelector('h1[class*="title"]') which means it selects some class with the word "title" in it. So product_title, news_title, something_title will work. That way you can have other <h1> elements in the <div> as well if you happen to want to add them (you just have to make sure they don't have a class with the word "title" in those).
I am trying to Set files picked using filepiker as List view datasource.
In Windows 8 using Javascript.
HTML:
<div id="smallListIconTextTemplate" data-win-control="WinJS.Binding.Template">
<div class="smallListIconTextItem">
<img src="#" class="smallListIconTextItem-Image" data-win-bind="src: picture" />
<div class="smallListIconTextItem-Detail">
<h3 data-win-bind="innerText: title"></h3>
<h6 data-win-bind="innerText: text"></h6>
</div>
</div>
</div>
<div id="listView_Id" data-win-control="WinJS.UI.ListView" data-win-options="{
itemDataSource: FileData.itemList.dataSource,
itemTemplate: select('#smallListIconTextTemplate'),}">
JS:
var dataArray = new Array();
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.list;
openPicker.fileTypeFilter.replaceAll([".epub"]);
var file;
openPicker.pickMultipleFilesAsync().then(function (files)
{
if (files.size > 0)
{
for (var i = 0; i < files.size; i++)
{
dataArray.push({
title: files[i].displayName,
text: "Author",
picture: "/images/BookImage.jpg"
});
var dataList = new WinJS.Binding.List(dataArray);
var publicMembers =
{
itemList: dataList
};
WinJS.Namespace.define("FileData", publicMembers);
I have array with file data. But unable to get in ListView
There is a binding issue in the code. FileData.itemList is not initialized at the time of page ui initialization. Right way to do that will be to have a view model observable class with itemList member and bind it to the DOM. Data Binding topic might help.
otherwise putting this should make it work. You may have to fix up your template to get the display right.
listView_Id.winControl.itemDataSource = dataList.dataSource;
I have a winJS list which is full of images. When a user clicks on an image, they are being sent to a second page. Is there any way of being able to determine which image the user clicked on page 1 (each image, when clicked, goes to the same page 2 but with a custom div). Here is my list declared and then I am push items to it:
var names_Array = [];
var names_List = new WinJS.Binding.List(names_Array);
var idPL;
names_List.push({ name: "man 1", image: "image/man1.png", ClientID: "1111" });
names_List.push({ name: "man 2 ", image: "image/man2.png", ClientID: "2222" });
idPL = document.getElementById("names_List");
idPL.addEventListener("iteminvoked", onclickItem);
function onclickItem(e) {
console.log("Item clicked");
}
A the minute I am populating the div based on which item was last pushed to the list, but I need this to be more flexible and be able to select the first item (even after a second one has been added)
EDIT: I AM NOW GETTING AN ERROR 'Unable to get property 'addEventListener' of undefined or null reference'. I THOUGHT I had defined it in my code above
To get the detail of which item is clicked in winjs listview we can use itemInvoke event of the Winjs listview.
<div id="itemsList" data-win-control="WinJS.Binding.Template" style="display:none;">
<div data-win-bind="className: type">
<img src="#" style="width: 100px; height: 100px;"
data-win-bind="alt: title; src: picture" />
<div>
<h4 data-win-bind="innerText: title" style="width:100px; height:20px;"></h4>
</div>
<div>
<img id="like"src="images/like.png" class="win-interactive" data-win-bind="alt:title; onclick: LikeClick;" />
</div>
</div>
</div>
<div id="UserListView" data-win-control="WinJS.UI.ListView" style="border-top: 5px solid #000; min-width:500px;"
data-win-options="{
selectionMode:'multi',
itemTemplate:select('#itemsList'),
layout:{
type:WinJS.UI.GridLayout}}"
>
</div>
then in the js
UserListView.addEventListener("iteminvoked", ItemInvoke);
function ItemInvoke(evt) {
var name=evt.detail.itemPromise._value.data.title;
var picturePath=evt.detail.itemPromise._value.data.picture;
}
Here in this listview we are only displaying the image and title of the user.
You can reformat your image urls to include:
A hash: image.html#man1.png
A query string: image.html?image=man1.png
And then use those to extract information from the URL using JavaScript for when the 2nd page is loaded.
Either assign an eventListener globally and check which was clicked and do something, or assign an eventListener per item and do whatever you require.
UPDATE: I am unable to demonstrate using WinJS, but this example should suffice.
HTML
<ul id="names_List"></ul>
Javascript
var names_Array = [],
idPL = document.getElementById("names_List");
names_Array.push({
name: "man 1",
image: "image/man1.png",
ClientID: "1111"
});
names_Array.push({
name: "man 2 ",
image: "image/man2.png",
ClientID: "2222"
});
names_Array.forEach(function (item) {
var li = document.createElement("li"),
img = document.createElement("img");
img.name = item.name;
img.src = item.img;
li.appendChild(img);
idPL.appendChild(li);
});
function onclickItem(e) {
if (e.target.tagName === "IMG") {
console.log("Item clicked", e.target.name);
}
}
idPL.addEventListener("click", onclickItem, false);
On jsfiddle
The best and easiest way you can do this is by declaring a namespace with the value of the image inside an eventlistener for selectionchanged, like this:
listview.addEventListener("selectionchanged", function (item) {
listview.selection.getItems().done(function (items) {
WinJS.Namespace.define("imageInformation", {
seletedImage: items[0].data.image,
});
}, false);
After the namespace is declared, you can access it on the other page:
var path = imageInformation.selectedImage;
So i have a html layout in which there are blocks (there are no fix number of them, because they can be created dynamically).
In these blocks there are boxes (again, they can be created dynamically)
The boxes contain *html element*s and also have different data attributes
So i need to create an object which looks like this
block1 = {
box1 : {
id : box1.data('id'),
content : box1.html()
},
box2 : {
id : box2.data('id'),
content : box2.html()
}
},
block2 = {
box3 : {
id : box3.data('id'),
content : box3.html()
}
}
Please don't write that the syntax is not correct, i know. I just tried to somehow illustrate what i want.
So my question is how do i do this with the help of jQuery?
Thank you in advanced
You can select all blocks and boxes and iterate over each of them using .each [docs]:
var blocks = {};
$('.block').each(function(index) {
var boxes = {};
$(this).find('.box').each(function(index) {
boxes['box' + index] = {
id: $(this).data('id');
content: $(this).html();
};
});
blocks['block' + index] = boxes;
});
You might not need an object of objects though, maybe an array of array suffices or would be even better, depending on what you intend to do with the data.
To learn more about how objects work, have a look at MDN - Working with Object.
Here is an idea:
1- Iterate over all of the blocks using some CSS selector.
2- Create a generic JS object and set a collection attribute called "boxes" to be an array
3- For each one, iterate over all the boxes inside it, again, using some CSS selector.
4- Create a generic JS object for each box and set the attributes as needed.
Code version
I think something like this would work (not tested):
var blocks = new Array();
$(".blocks").each(function(b) {
var my_block = {boxes: new Array()};
var $block = $(b);
$(".box", $block).each(function(box) {
var $box = $(box);
my_block.boxes.push({id: $box.attr("id"), content: $box.html()});
});
blocks.push(my_block);
});
You should take a look at Knockout.js, it's very comfortable to build an application like yours.
In detail: use Objects. Build an array for yourself, containing Objects with e.g. Block Name and all Child nodes.
<div id="lanesContainer" data-bind="foreach: blocks">
<div id="" class="dropLane laneDefault ui-widget-header ui-dialog ui-widget ui-corner-all ui-front ui-resizable">
<div class="ui-dialog-titlebar ui-helper-clearfix" data-bind="drop: {value: $data.dropTask}">
<p class="laneheader" data-bind="text: $data.title">Lane</p>
</div>
<ul data-bind="foreach: box">
<li class="ui-dialog-content laneItem" data-bind="drag: {value: $data}">
<div class="ui-widget-header laneItemHeader" data-bind="text: $data.Title"></div>
<div class="ui-widget-content laneItemBody" data-bind="text: $data.Description"></div>
<div class="ui-widget-content laneItemFooter">
<div class="ui-corner-all ui-state-default notification-important">
<span class="ui-icon ui-icon-notice" title="sometitle" data-bind="css: {'notification-important-hide': !$root.isElementImportant($data) }"></span>
</div>
</div>
</li>
</ul>
</div>
</div>
Is this useful?
Here is how to get an Object with nested Array of Childs:
function laneObject(title) {
var obj = new Object();
obj.title = title; //Identifier for Lane
obj.childs = []; //Elements of Lane to display
return obj;
}
I am not entirely sure of what your question is, but if you want to create blocks and boxes dynamically, I suggest you first of all use Arrays.
//All dynamically created blocks
blocks = [];
//Create blocks
for(var i = 1; i < 3; i++) {
var block = {
//All dynamically generated bloxes
boxes = [];
};
//Create boxes
for(var j = 1; j < 4; j++) {
block.box[j] = {
id : j,
content : '<span>html for box' + j + '</span>'
}
}
blocks[i] = block;
}