Mootools each function works for last fund in array only - javascript

I got following markup twice on the page with different id for each .option div and it might be duplicate few more times
<div class="optionsHolder"></div>
<div class="option selected">Select</div>
<div id="option238" class="option">Option1</div>
<div id="option239" class="option">Option2</div>
<div id="option261" class="option">Option3</div>
I am trying to grab all options and place them inside optionsHolder , this works but only for the last optionHolder on the page , this is js
var optionscont = $$('.optionsHolder');
var findoptions = $$('.option');
optionscont.each(function (element){
element.adopt(findoptions);
});
any help would be appreciated. thank you!

This i think does what you want JSFiddle
function GetHolder( option )
{
var holder = option.getPrevious( ".optionsHolder" )
if( holder )
{
holder.adopt( option );
}
}
var findoptions = $$('.option');
Array.each( findoptions, function( item) { GetHolder( item ) } );

Related

Filter data in ng-repeat to display only the clicked item with Angularjs

Please help a little bit.
I have a list of 7 events displayed already with Angularjs. I'd like when I click on the <h2> (the event name) of some event, to open an ovelay that displays the same data from the database but only for this event which is clicked.
I'm sure that 'filter' will do the work but it seems I'm doing something wrong.
Here is my code. The ng-app and ng-controller are in the <main> tag.
Angularjs version: 1.7.9
My Html:
<main ng-app="eventsApp" ng-controller="eventsCtrl">
<!-- Overlay that holds and displays a single event -->
<div>
<div ng-repeat="x in singlePageEvent | filter:hasName(x.eventName)">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
</div>
<!-- A list with all the events -->
<div ng-repeat="x in events">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
</main>
My script:
let eventsApp = angular.module('eventsApp', []);
this filter below is not working at all. It continues to show all the events.
eventsApp.filter('hasName', function() {
return function(events, evName) {
var filtered = [];
angular.forEach(events, function(ev) {
if (ev.eventName && ev.eventName.indexOf(evName) >-1) {
filtered.push(ev);
}
});
return filtered;
}
});
eventsApp.controller('eventsCtrl', function($scope, $http) {
let x = window.matchMedia("(max-width: 450px)");
let singleEventOverlay = angular.element(document.querySelector('div.single-event.overlay'));
let singleEvent = singleEventOverlay;
function responsiveEventImages(x) { //this displays the list with events
if (x.matches) {
$http.get('./includes/events_res.inc.php').then(function(response) {
$scope.events = response.data.events_data;
});
} else {
$http.get('./includes/events.inc.php').then(function(response) {
$scope.events = response.data.events_data;
});
}
}
...and then by invoking singleEventOpen() the overlay appears, but it displays all the data, not just the clicked event
$scope.singleEventOpen = function(singleEvent) {
let clickedEvent = singleEvent.eventName; //I got the value of each h2 click thanx to #georgeawg but now what?
console.log("Fetching info for ", singleEvent.eventName);
$http.get('./includes/single_event.inc.php').then(function(response) {
$scope.singlePageEvent = response.data.events_data;
});
singleEventOverlay.removeClass('single-event-close').addClass('single-event-open');
}
});
The php file with the database extraction is working fine so I won't display it here.
What should I do to make the overlay display only the event which <h2> is clicked?
Here is a pic of the list with events
Here is a pic of the overlay
Thanx in advance.
EDITED
I got the value of each h2 click thanx to #georgeawg but now what?
UPDATE
Hey, thanx a lot #georgeawg . After many attempts I finally did this:
$scope.singleEventOpen = function(singleEvent) {
$http.get('./includes/single_event.inc.php').then(function(response) {
let allEvents = response.data.events_data;
for (var i = 0; i < allEvents.length; i++) {
singleEvent = allEvents[i];
}
});
console.log('Fetching data for', singleEvent);
$scope.ex = singleEvent;
});
And it works well.
Change the ng-click to pass an argument to the singleEventOpen function:
<div ng-repeat="x in events">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
Then use that argument:
$scope.singleEventOpen = function(singleEvent) {
console.log("Fetching info for ", singleEvent.eventName);
//...
//Fetch and filter the data
$scope.ex = "single item data";
}
Adding an argument is the key to knowing which <h2> element was clicked.
Update
Don't use ng-repeat in the overlay, just display the single item:
<!-- Overlay that holds and displays a single event -->
̶<̶d̶i̶v̶ ̶n̶g̶-̶r̶e̶p̶e̶a̶t̶=̶"̶x̶ ̶i̶n̶ ̶s̶i̶n̶g̶l̶e̶P̶a̶g̶e̶E̶v̶e̶n̶t̶ ̶|̶ ̶f̶i̶l̶t̶e̶r̶:̶h̶a̶s̶N̶a̶m̶e̶(̶x̶.̶e̶v̶e̶n̶t̶N̶a̶m̶e̶)̶"̶>̶
<div ng-if="ex"">
<div>
<img ng-src="{{ex.eventImgSrc}}" alt="{{ex.eventImgName}}"/>
<h2 class="event-name">{{ex.eventName}}</h2>
<p>{{ex.eventTime}}</p>
<p>{{ex.eventPlace}}</p>
</div>
</div>

How can I change the default ordered and unordered list providing various options in Jodit Editor?

I am being able to provide option's in the menu bar but when I click on any of the option it's working absolutely fine,but if I tried to select twice it is changing at all places.
For Ex.
I want to make a ordered list such as:
1.Some Text here
a.option 1 b.option 2
c.option 3 d.option 4.
When I am trying to select some text its also converting 1 to A.
Please help.Thanks in advance
document.execCommand('insertUnorderedList',true,null);
let selectedStyle = event.target.parentNode.classList.value;
$('li').attr('id', function(i) {
return 'unorder'+(counter+1);
});
$('ol > li').css({'list-style-type':selectedStyle});
You can ignore the counter part its not required.I was trying to put id at every element and use jquery to update only that part.
let counter = 0;
document.querySelectorAll (".unorder-list-select .unorder-list-main .unorder-container ul").forEach((elem)=>{
elem.addEventListener("click",(event)=>{
counter++;
$('li').attr('id', function(i) {
return 'unorder'+(counter+1);
});
$('ul > li').css({'list-style-type':selectedStyle});
}
HTML
<div class="order-list-select" id="orderList" draggable="true">
<div>
<span class="jodit_popup_triangle"></span>
<div class="math-toolbar-top" id="orderlistHeader"></div>
<div class="order-list-main">
<div class="order-list-container"></div>
<div class="order-container">
<ol class="upper-roman">
<li><hr></li>
</ol>
<ol class="decimal">
<li><hr></li>
</ol>
</div>
</div>
</div>
</div>
Actual
1.text
2.text
Some text here
1.Txt
2.Txt
Expected
1.text
2.text
Some text here
a.Txt
b.Txt
I did it by Jquery don't know if its right approach but it has made me achieve my task.
Below is the code for my this.
document.querySelectorAll(".unorder-list-select .unorder-list-main .unorder-container ul").forEach((elem)=>{
elem.addEventListener("click",(event)=>{
counter++;
document.execCommand('insertUnorderedList',true,null);
let selectedStyle = event.target.parentNode.classList.value;
let select = window.getSelection().focusNode.parentElement.parentElement;
let ul_id = ""
$(select).attr('id', function(i) {
ul_id = "unorder"+(counter);
return ul_id;
});
if(selectedStyle == "right-arrow"){
$('#'+ul_id).css({'list-style-image':`url('icons/list-right-editor.svg')`});
}else if(selectedStyle == "open-square"){
$('#'+ul_id).css({'list-style-image':`url('icons/square-open-editor.svg')`});
}else{
$('ul').attr('type',function(){
return selectedStyle;
})
$('#'+ul_id).css({'list-style-type':selectedStyle});
}
document.querySelector(".unorder-list-select").remove();
})
});
Please change the classess accordingly to get the tag and click.

jQuery if div id contains number from array... do something

I have an array of numbers which I need to target on pages like this:
sku = [1243,3453,6453, ..... ]
These values are inside a div on a page like this:
<div id="product_1243">
<div class="block">
test
</div>
</div>
<div id="product_3453">
<div class="block">
test
</div>
</div>
<div id="product_6453">
<div class="block">
test
</div>
</div>
I have created a function to check if a number from the array exists in this div:
sku.forEach(function (element) {
if ($("div[id*='product_item_code_" + element +"']").length) {
alert("this exists" + element);
}
});
This works, but I want to ask two questions:
1) How to use insertAfter below to insert some HTML after each <div class="block">. It should only get inserted if the statement is true of course.
$("<p>test!</p>").insertAfter(....);
2) if this is best for performance because my array is actually much much bigger with over 1000 values to check for in the forEach.
Thanks
Use append or appendTo if block is the only child of product_***
var $el = $("div[id*='product_item_code_" + element +"']");
if ( $el.length) {
alert("this exists" + element);
$("<p>test!</p>").appendTo( $el );
}
or
var $el = $("div[id*='product_item_code_" + element +"']");
if ( $el.length) {
alert("this exists" + element);
$el.append( "<p>test!</p>" )
}
In case block is not the only child
var $el = $("div[id*='product_item_code_" + element +"']");
if ( $el.length) {
alert("this exists" + element);
$("<p>test!</p>").insertAfter( $el.find( ".block" ) );
}
How about this? Store products instead of querying it each time as it affects performance.
const products = $('div[id^=product_item_code]')
products.each((index, element) => {
if(sku.includes(element.id.split('_')[1]))
$('.block', element).after('<p>test!</p>')
})

How to iterate through all div and get specific property?

what I'm trying to do is iterate over a collection of div, contained in a parent container. My structure is the following:
<div id='main'>
<div data-id='2'>
</div>
<div data-id='3'>
</div>
</div>
My goal is take the field data-id of each div and create an array collection. Previously I used the select where do I get each value of available option, like this:
var available_services = $('#selected-service').find('option', this).map(function ()
{
return this.value;
}).get();
But now I'm using a div collection instead of the select. How I can iterate through all available div?
This should return all data-id values in a list:
var available_services = $('#main').find('div').map(function (item)
{
return item.attr('data-id');
});
I didn't test this, but I think should do the job. (maybe you need to tweak a little bit)
I believe this will do it:
var available_services = [];
$('#main div').each(function(){
available_services.push($(this).data( "id" ));
})
This is the easy way to go:
$(document).ready(function() {
var myCollection = [];
$('#main div').each(function(){
var dataDiv = $(this).attr('data-id');
myCollection.push(dataDiv)
})
});
Try this:
(function(){
var main = $("#main");
var divs = $(main).find("div");
var arrId = divs.map(function(index, div){
return $(div).attr("data-id");
});
console.log(arrId);
})()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='main'>
<div data-id='2'>
</div>
<div data-id='3'>
</div>
</div>

MVC Duplicating Drop-Down list on selection

I am trying to make a page where the user selects an item in a drop-down list, which then will create a duplicate drop-down list. The last drop-down list always needs to create a new one once an item is selected.
Using the following javascript code
<script type="text/javascript">
$(document).ready(function () {
$(function listselect() {
if (x == null) {
var x = 1;
}
//need to increment x after the completion of the following funciton so the function will trigger on different drop-down lists
$('#FooId' + x).change(function q() {
$('#FooId' + x).clone().attr('id', 'FooId' + (++x)).attr('name', 'Selected').insertAfter('#FooId' + (x - 1))
//return x;
});
//return x;
});
});
</script>
and the razor html
<div class ="container">
<div class="label">
#Html.LabelFor(Function(model) model.Foo, "Foo")
</div>
<div class="foo" id="foo">
#Html.DropDownList("FooId", Nothing, "--Select--", New With {.Name = "Selected", .Id = "FooId" & "1"})
//#*#Html.ValidationMessageFor(Function(model) model.Foo)*#
</div>
</div>
I am able to make the first list clone itself, but how do you return x from function q so that it can be used by its own function (Function q needs to trigger when an item is selected in Foo1, then Foo2, etc.).
(Sorry if this doesn't make sense, I am not sure how to word it. I am very new to coding). Thanks.
If I got you right, you don't need most of your code. And it's easier to use classes here. Just do it like this:
$(document).ready(function () {
$('.foo').on('change', function(e) {
var newFoo = $(e.target).clone();
$(e.target).after(newFoo);
});
});
And your markup part should be like this:
<div class ="container">
<div class="label">
#Html.LabelFor(Function(model) model.Foo, "Foo")
</div>
<div class="foo" id="foo">
#Html.DropDownList("FooId", Nothing, "--Select--", new {name = "Selected", #class = "foo" })
</div>
</div>
I don't remember Html.DropDownList signature so I created simple jsfiddle without it. I hope this is what you needed.
UPDATE:
I've corrected my fiddle as follows:
$(document).on('change', '.foo:last', function(e) {
var newFoo = $(e.target).clone();
$(e.target).after(newFoo);
});
Now it doesn't add extra selects if it's not the last select that was changed.

Categories