vendredi 29 mai 2015

How to hide Boostrap Dropdown submenu when other menu of dropdown is clicked?

I am displaying bootstrap dropdownmenu and on click of any parent dropdown value i am displaying other child dropdown. when i click on a value in dropdown ,the childmenu opens and when i click on next dropdown value ,the previous chidmenu dropdown is not closed.I want to close the previous childdropdown menu if any other value of parent menu is clicked.How to achieve this?Please help! Thanks in advance

Here is my code:

<div class="dropdown">
    <ul id="ddlTest" class="ddltestdd dropdown-menu" role="menu">
        @foreach (var item in (IEnumerable<SelectListItem>)ViewBag.testresults)
        {
            <li class="dropdown-submenu">
                <span class="dropdown-toggle" data-toggle="dropdown">@item.Text</span>
                <span class="testCaret" aria-hidden="true" style="float:right;margin-top:5px;">
                </span>
                <ul class="ddltestdd dropdown-menu dropup" role="menu" id="testorder_@item.Text">
                    <li>
                        <span class="TestBySubmenu">T1</span>
                    </li>
                    <li>
                        <span class="TestBySubmenu">T2</span>
                    </li>
                </ul>
            </li>
        }
    </ul>
</div>

Jquery:

var testText;
                    $(".dropdown-submenu").click(function () {
                            $(this).find(".dropdown-submenu").removeClass('open');
                    $(".dropdown-submenu:hover > .dropdown-menu").css('display', 'block');
                    testText;= $(this).text();
                    return false;
                });



        $('.dropdown-menu li span').click(function () {

        var Allowpageload = testText;
        if ((Allowpageload == "T1") || (Allowpageload == "T2")) {
          //load page
            $(".dropdown-submenu:hover > .dropdown-menu").css('display', 'none');
            $('[id^="testorder_]').dropdown('toggle');
            $('[data-toggle="dropdown"]').parent().removeClass('open');
            }

Geojson (GetJSON) and remove higlight (mouse out) on Leaflet

I don't manage to remove the highlight on a map since I call the data with $.getJSON. When I use the basic map (http://ift.tt/1Kt8lC1) all works, but when I call a geojson file with Jquery (not a leaflet json template with var = {json}), the highlight doesn't remove.

Example of what doesn't work (you can see it at : http://ift.tt/1G6JiXs) I think it comes from the function resetHighlight(e) but I don't manage to resolve it.

    function styleeurope(feature) {
        return {
            weight: 1.5,
            color: '#222',
            opacity:0.5,
            fillOpacity: 0.7,
            fillColor: getColor(feature.properties.statTOTAL)
        };
    }
    function highlightFeature(e) {
        var layer = e.target;

        layer.setStyle({
            weight: 3,
            color: 'black',
            opacity: 0.7,
            dashArray: '0',
            fillOpacity: 0.5,
            fillColor: '#fff200',
        });


        info.update(layer.feature.properties);
    }

// reset highlight //

function resetHighlight(e) {
        geojson.resetStyle(e.target);
        info.update();
    }

// OnEachFeature

function onEachFeature(feature, layer) {
        layer.on({
            mouseover: highlightFeature,
            mouseout: resetHighlight,       
        });
    }

// GeoJSON call data //

$.getJSON("data/europe_fao.json",function(dataeurope){ var geojson = L.geoJson(dataeurope,{
        style: styleeurope,
        onEachFeature: onEachFeature} ).addTo(map);  });

Thank you so much if you manage to help me !

Json response to ajax

The data is inserted and i receive in console the json response but the page move for the insert php and gives the json response So i start in page A (form) and after submit moves to page B (insert)giving me the json response. I'm having a problem getting the response of the following php into ajax

if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $uploadfile)) {

$target_path = "/uploads/" . basename($_FILES['fileToUpload']['name']);
$sql = "INSERT INTO `ebspma_paad_ebspma`.`formacoes`(idescola, nome, inicio, horas, local, destinatarios, dataLimite, visto, path) VALUES(?, ?, ?, ?, ? ,?, ?, ?, ? )";
$stmt = $mysqli->prepare($sql);
if ($stmt === false) {
    trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $mysqli->error, E_USER_ERROR);
}
$stmt->bind_param('issssssis', $escola, $form, $data, $horas, $local, $dest, $datas, $visto, $target_path);
if (!$stmt->execute()) {
    echo json_encode(array('status' => 'error', 'message' => 'Opppss...A formação não foi gravada'));
}
} else {
echo json_encode(array('status' => 'error', 'message' => 'Opppss...A formação não foi gravada'));
}
$stmt->close();
echo json_encode(array('status' => 'success', 'message' => 'Nova formação gravada'));

This is my ajax

$.ajax({
            url: 'nova_formacaoBD.php',
            dataType: 'json',
            data: data,
            success: function(data) {
                $('#ajaxDivOk').html('Informação: Esta formação foi registada na base de dados');
                if(data.status == "success"){ 
                   $('#ajaxDivOk').append(data.message);
                }
             }
          });

And this is my form

 <form action="nova_formacaoBD.php" method="post" id="formacao" name="formacao" enctype="multipart/form-data">

Place the scrollbar at the bottom of viewport

I'm working on a rather complex layout. There are two regions, red and blue, that must scroll vertically simultaneously but the right region (blue) must be able to scroll horizontally independently of the other region.

I managed to do that, but the scrollbar is always at the bottom of the div and I need the scrollbar always visible at the bottom of the viewport.

Is it possible to achieve this with HTML/CSS? What plain JS or jQuery plugins could help with this?

JSFiddle Demo

Ajax fails to pass html page as parameter to code behind

I am working on a task to convert a webpage to pdf file using SelectPdf. SelectPdf does not support dynamic pages. So I want to use Ajax to pass the webpage as html.

For some reason when I passed ordinary string it works but when I change to use a variable (with html as value) it doesn't. I don't know whether the html content is too large, however I tried with less content and still the same issue. Any help will be appreciated.

The project is language is VB.Net, the page is vbhtml and code behind is a controller.

Please see below the code I have implemented:

VIEW

           var btn = $('#BtnCreateHtmlToPdf');

           btn.click(function () {

            var theHtml = document.documentElement.innerHTML;

            //Just to see there is a value
            alert(theHtml)  

            $(function () {
                $.ajax({
                    type: 'post',
                    url: "/CreatHtmlToPdf/CreatePdf",
                    dataType: "html",
                    data: { HTML: theHtml }
                })
                .done(function (results) {
                    alert("Html data: " + results);
                });
            });
           });

CODE BEHIND

Public Class CreatHtmlToPdfController
    Inherits Controller

    ' GET: CreatHtmlToPdf
    Function Index() As ActionResult

        Return View()
    End Function

    <HttpPost()>
    Function CreatePdf(ByVal HTML As String) As ActionResult

        Dim doc As PdfDocument

        ' read parameters from the webpage
        Dim htmlString As String = HTML

        ' instantiate a html to pdf converter object
        Dim converter As New HtmlToPdf()

        ' create a new pdf document converting an url
        If (HTML <> String.Empty) Then

            doc = converter.ConvertHtmlString(htmlString)


        End If


        ' save pdf document
        Dim pdf As Byte() = doc.Save()

        ' close pdf document
        doc.Close()

        ' return resulted pdf document
        Dim fileResult As FileResult = New FileContentResult(pdf, "application/pdf")
        fileResult.FileDownloadName = "Results_page.pdf"
        Return fileResult

    End Function

    'Declaration
    'Public Property EnablePageMethods As Boolean

End Class

WAI ARIA screenreader not reading dynamically added rows

I've scenario where I am trying to add rows dynamically to a table using Ajax. I've following table structure:

<table class="user-table table" id="usersTable">
    <thead>
      <tr>
        <th class="user-col user-name">Name</th>
        <th class="user-col user-email">Email</th>
        <th class="user-col user-status">Admin</th>
        <th class="user-col user-i-col">Active</th>
        <th class="user-col user-i-col">Actions</th>
      </tr>
    </thead>
</table>

Now I am trying to dynamically add/remove rows to/from table using JavaScript/jQuery. There are basically 2 different ways I am doing this:

  1. looping through JSON data, creating tbody, rows and cell and appending the tbody to target table using JavaScript OR
  2. using $(element).append(HTML) to append the HTML returned by Ajax call.

if I use JavaScript to create tbody, rows and data cells, NVDA correctly reads the added rows Ref: updateTableAsync . So if I add 3 rows to table this way, NVDA will read table with 4 rows and 5 columns, which is correct.

However, if I try to append the returned html directory into table using $.append or $.html, it does not identify the rows that were added dynamically. Ref: updateTableContentAsync

Here is the JSON that is returned:

{"users":[
    {"name":"ABC","email":"ABC@mailcatch.com","admin":true, "active":true,"action":"Remove" },
    {"name":"XYZ","email":"XYZ@mailcatch.com","admin":false, "active":false,"action":"Remove"},
    {"name":"ASDF","email":"ASDF@mailcatch.com","admin":false, "active":true,"action":"Remove"}
    ]
}

(function(global, window, $) {
      'use strict';
      //Accessible Ajax Loading Test
      var AALoadingTest = AALoadingTest || {};
      AALoadingTest.AjaxUtil = (function() {          
          
          
          var makeDataCell = function(row, index, data ) {
            var cell = row.insertCell(index);
            var cellText  = document.createTextNode(data)
            cell.appendChild(cellText);
          };

          var setFocus = function(element, fallbackElement) {
            var focusElement = document.getElementById(element); 
            if(typeof focusElement == 'undefined') {
              focusElement = document.getElementById(fallbackElement);
            }                
            window.setTimeout(function(){
              window.console.log(focusElement);
              focusElement.focus();
            }, 100);
          };

          //Method : 1 Update table content by looping through json data using native Javascript   
          var updateTableAsync = function(url, targetTable, targetContainer, focusContainer, announce) {
            
            //TODO: remove timeout when in prod, need while testing because locally changes are loading too fast
            window.setTimeout( function() {
              $.get(url, function(data){              
                
                var tempTargetTBody = document.getElementById(targetContainer);
                var target = document.getElementById(targetTable);
                var targetTBody = document.createElement('tbody');
                targetTBody.innerHTML = '';
                targetTBody.setAttribute('aria-live', tempTargetTBody.getAttribute('aria-live'));
                // targetTBody.setAttribute('aria-atomic', tempTargetTBody.getAttribute('aria-live'));
                tempTargetTBody.remove();
                targetTBody.setAttribute('id',targetContainer);
                
                $.each(data.users, function(key, value){
                  var row = targetTBody.insertRow(targetTBody.rows.length);
                  makeDataCell(row, 0, value.name);
                  makeDataCell(row, 1, value.email);
                  makeDataCell(row, 2, value.admin ? 'Yes': 'No');
                  makeDataCell(row, 3, value.active ? 'Yes': 'No');
                  makeDataCell(row, 4, value.action);
                });
                target.appendChild(targetTBody);           
              })
            },5000);
          };

          //Method : 2 Update table content by inserting HTML element by looping through JSON returned into table  
          var updateTableHTMLAsync = function(url, targetTable,  targetContainer, focusContainer, announce) {                         
            

            //TODO: remove timeout when in prod, need while testing because locally changes are loading too fast
            window.setTimeout( function() {
              $.get(url, function(data){              
                
                var targetElement = $('#'+targetContainer);
                targetElement.remove();
                targetElement = $('<tbody></tbody>').attr({'aria-live': 'polite', 'id': targetContainer});
                
                $.each(data.users, function(key, value) {
                  window.setTimeout(function() {
                    var row = $("<tr> </tr>");
                      targetElement.append(row);
                      row.append($("<td></td>").text(value.name));
                      row.append($("<td></td>").text(value.email));
                      row.append($("<td></td>").text((value.admin ? 'Yes': 'No')));
                      row.append($("<td></td>").text((value.active ? 'Yes': 'No')));
                      row.append($("<td></td>").text(value.action));
                  },100);
                });      
                $("#"+targetTable).append(targetElement);         
                
              })
            },5000);
          };

          //Method : 3 Update table content by inserting HTML returned into table  
          var updateTableContentAsync = function(url, targetTable,  targetContainer, focusContainer, announce) {                         
            

            //TODO: remove timeout when in prod, need while testing because locally changes are loading too fast
            window.setTimeout( function() {
              $.get(url, function(data){              
                
                var targetElement = $('#'+targetContainer);
                targetElement.remove();
                targetElement = $('<tbody></tbody>').attr({/*'aria-live': 'polite',*/ 'id': targetContainer});
                $("#"+targetTable).append(targetElement);                
                
                targetElement.append($(data));                
              })
            },5000);
          };

          return {
            updateTableAsync: updateTableAsync,
            updateTableHTMLAsync: updateTableHTMLAsync,
            updateTableContentAsync: updateTableContentAsync,
            removeLoader: removeLoader,
            loader: loader
          };
      })();
      
      $("#asyncHTML").on("click", function(e){ 
        e.stopPropagation();
        AALoadingTest.AjaxUtil.updateTableHTMLAsync(
          $(this).attr('data-resource'),
          $(this).attr('data-target-table'),
          $(this).attr('data-target-element'),
          $(this).attr('data-focus-element'),
          true
        );       
        return false;
      });

      $("#asyncJSON").on("click", function(e){ 
        e.stopPropagation();
        AALoadingTest.AjaxUtil.updateTableAsync(
          $(this).attr('data-resource'),
          $(this).attr('data-target-table'),
          $(this).attr('data-target-element'),
          $(this).attr('data-focus-element'),
          true
        );       
        return false;
      });

      $("#asyncHTMLContent").on("click", function(e){ 
          e.stopPropagation();
          AALoadingTest.AjaxUtil.updateTableContentAsync(
            $(this).attr('href'),
            $(this).attr('data-target-table'),
            $(this).attr('data-target-element'),
            $(this).attr('data-focus-element'),
            true
          );       
          return false;
      });


      })(this, window,jQuery);
<link href="http://ift.tt/1mDOveJ" rel="stylesheet"/>
<script src="http://ift.tt/1qRgvOJ"></script>
<script src="http://ift.tt/1h4yM0u"></script>
<main>
      <div class="container">     
        <div class="container-fluid">         
          
          <h1>Dynamic Tables</h1>        
          <p> Load JSON using Ajax get, use JavaScript to create tbody, rows and data cell and append the tbody to table using appendChild</p>
          <br>
            <a class="btn btn-primary async" id="asyncJSON" data-target-table="usersTableJSON"
                role="button" data-target-element="userTableBodyJSON" data-focus-element="asyncContentJSON" 
                href="javascript:;" data-resource="data/users.json">
                Load Users <span class="sr-only">Load json Data</span>
            </a>
          <br>
          <br>
          <div class="panel" id="asyncContentJSON">
            <table class="user-table table" id="usersTableJSON">
            <thead>
              <tr>
                <th class="user-col user-name">Name</th>
                <th class="user-col user-email">Email</th>
                <th class="user-col user-status">Admin</th>
                <th class="user-col user-i-col">Active</th>
                <th class="user-col user-i-col">Actions</th>
              </tr>
            </thead>
            <tbody id="userTableBodyJSON" aria-live="polite"></tbody>            
          </table>
          </div>

          <br>
          <p> Load JSON using Ajax get, use jQuery to create tbody, rows and data cell and append the tbody to table using $.append</p>
          <br>
            <a class="btn btn-primary async2" id="asyncHTML"
                role="button" data-target-element="userTableBodyHTML" data-target-table="usersTableHTML" data-focus-element="asyncContentHTML" 
                href="data/rows.html" data-resource="data/users.json">
                Load Users<span class="sr-only">Load HTML Data</span>
            </a>
          <br>

          <br>
          <div class="panel" id="asyncContentHTML">
            <table class="user-table table" id="usersTableHTML">
            <thead>
              <tr>
                <th class="user-col user-name">Name</th>
                <th class="user-col user-email">Email</th>
                <th class="user-col user-status">Admin</th>
                <th class="user-col user-i-col">Active</th>
                <th class="user-col user-i-col">Actions</th>
              </tr>
            </thead>
            <tbody id="userTableBodyHTML" aria-live="polite"></tbody>
          </table>
          </div>

          <br>
          <p> Load JSON using Ajax get, use JavaScript to create tbody, rows and data cell and append the tbody to table using $.html</p>
          <br>
            <a class="btn btn-primary async2" id="asyncHTMLContent"
                role="button" data-target-element="userTableBodyHTMLContent" data-target-table="usersTableHTMLContent" data-focus-element="asyncContentHTMLContent" 
                href="data/rows.html" data-resource="">
                Load Users<span class="sr-only">Load HTML View</span>
            </a>
          <br>
          <br>
          <div class="panel" id="asyncContentHTMLContent">
            <table class="user-table table" id="usersTableHTMLContent">
            <thead>
              <tr>
                <th class="user-col user-name">Name</th>
                <th class="user-col user-email">Email</th>
                <th class="user-col user-status">Admin</th>
                <th class="user-col user-i-col">Active</th>
                <th class="user-col user-i-col">Actions</th>
              </tr>
            </thead>
            <tbody id="userTableBodyHTMLContent" aria-live="polite"></tbody>
          </table>
          </div>
        </div>        
      </div>
      <div id="overlay" class="hidden">          
        <span class="visuallyHidden" id="loadingMessage" role="status" aria-hidden="true"></span>
      </div>        
    </main>

One thing that I suspect here is: when I manually add rows one by one, NVDA is aware of individual DOM change, however, when I update the innerHTML all it know is "one update in DOM". Please let me know if someone has faced similar issue and how you fixed that.

Thanks

Using ':hidden' selector to find hidden elements in jquery

In jQuery, I can use $(':hidden') to find hidden elements, but I don't want to include the 0 size elements (width=0 and height=0).

How to achieve this?

I can't just judge if it is 0 size, because if one of its parents is hidden, I also want to select it.

For example:

<img id="e1" width="0" height="0" />
<div style="display:none;">
    <img id="e2" width="0" height="0" />
</div>

I want to select "e2",but not "e1".